1e254ffb9SDaniel Borkmann#!/usr/bin/env python3 2e254ffb9SDaniel Borkmann# SPDX-License-Identifier: GPL-2.0 3e254ffb9SDaniel Borkmann 4e254ffb9SDaniel Borkmannimport errno 5e254ffb9SDaniel Borkmannimport time 6e254ffb9SDaniel Borkmannfrom lib.py import ( 7e254ffb9SDaniel Borkmann ksft_run, 8e254ffb9SDaniel Borkmann ksft_exit, 9e254ffb9SDaniel Borkmann ksft_eq, 10e254ffb9SDaniel Borkmann ksft_ne, 11e254ffb9SDaniel Borkmann ksft_in, 12e254ffb9SDaniel Borkmann ksft_not_in, 13e254ffb9SDaniel Borkmann ksft_raises, 14e254ffb9SDaniel Borkmann) 15e254ffb9SDaniel Borkmannfrom lib.py import ( 16e254ffb9SDaniel Borkmann NetNS, 17e254ffb9SDaniel Borkmann NetNSEnter, 18e254ffb9SDaniel Borkmann EthtoolFamily, 19e254ffb9SDaniel Borkmann NetdevFamily, 20e254ffb9SDaniel Borkmann RtnlFamily, 21e254ffb9SDaniel Borkmann NetdevSimDev, 22e254ffb9SDaniel Borkmann) 23e254ffb9SDaniel Borkmannfrom lib.py import ( 24e254ffb9SDaniel Borkmann NlError, 25e254ffb9SDaniel Borkmann Netlink, 26e254ffb9SDaniel Borkmann cmd, 27e254ffb9SDaniel Borkmann defer, 28e254ffb9SDaniel Borkmann ip, 29e254ffb9SDaniel Borkmann) 30e254ffb9SDaniel Borkmann 31*1e822171SDaniel Borkmann 32*1e822171SDaniel Borkmanndef wait_until(cond, timeout=2.0, interval=0.05): 33*1e822171SDaniel Borkmann deadline = time.monotonic() + timeout 34*1e822171SDaniel Borkmann while not cond(): 35*1e822171SDaniel Borkmann if time.monotonic() >= deadline: 36*1e822171SDaniel Borkmann return 37*1e822171SDaniel Borkmann time.sleep(interval) 38*1e822171SDaniel Borkmann 39*1e822171SDaniel Borkmann 40*1e822171SDaniel Borkmanndef create_netkit(rxqueues, mode="l2"): 41e254ffb9SDaniel Borkmann all_links = ip("-d link show", json=True) 42e254ffb9SDaniel Borkmann old_idxs = { 43e254ffb9SDaniel Borkmann link["ifindex"] 44e254ffb9SDaniel Borkmann for link in all_links 45e254ffb9SDaniel Borkmann if link.get("linkinfo", {}).get("info_kind") == "netkit" 46e254ffb9SDaniel Borkmann } 47e254ffb9SDaniel Borkmann 48e254ffb9SDaniel Borkmann rtnl = RtnlFamily() 49e254ffb9SDaniel Borkmann rtnl.newlink( 50e254ffb9SDaniel Borkmann { 51e254ffb9SDaniel Borkmann "linkinfo": { 52e254ffb9SDaniel Borkmann "kind": "netkit", 53e254ffb9SDaniel Borkmann "data": { 54*1e822171SDaniel Borkmann "mode": mode, 55e254ffb9SDaniel Borkmann "policy": "forward", 56e254ffb9SDaniel Borkmann "peer-policy": "forward", 57e254ffb9SDaniel Borkmann }, 58e254ffb9SDaniel Borkmann }, 59e254ffb9SDaniel Borkmann "num-rx-queues": rxqueues, 60e254ffb9SDaniel Borkmann }, 61e254ffb9SDaniel Borkmann flags=[Netlink.NLM_F_CREATE, Netlink.NLM_F_EXCL], 62e254ffb9SDaniel Borkmann ) 63e254ffb9SDaniel Borkmann 64e254ffb9SDaniel Borkmann all_links = ip("-d link show", json=True) 65e254ffb9SDaniel Borkmann nk_links = [ 66e254ffb9SDaniel Borkmann link 67e254ffb9SDaniel Borkmann for link in all_links 68e254ffb9SDaniel Borkmann if link.get("linkinfo", {}).get("info_kind") == "netkit" 69e254ffb9SDaniel Borkmann and link["ifindex"] not in old_idxs 70e254ffb9SDaniel Borkmann ] 71e254ffb9SDaniel Borkmann nk_links.sort(key=lambda x: x["ifindex"]) 72e254ffb9SDaniel Borkmann return ( 73e254ffb9SDaniel Borkmann nk_links[1]["ifname"], 74e254ffb9SDaniel Borkmann nk_links[1]["ifindex"], 75e254ffb9SDaniel Borkmann nk_links[0]["ifname"], 76e254ffb9SDaniel Borkmann nk_links[0]["ifindex"], 77e254ffb9SDaniel Borkmann ) 78e254ffb9SDaniel Borkmann 79e254ffb9SDaniel Borkmann 80e254ffb9SDaniel Borkmanndef create_netkit_single(rxqueues): 81e254ffb9SDaniel Borkmann rtnl = RtnlFamily() 82e254ffb9SDaniel Borkmann rtnl.newlink( 83e254ffb9SDaniel Borkmann { 84e254ffb9SDaniel Borkmann "linkinfo": { 85e254ffb9SDaniel Borkmann "kind": "netkit", 86e254ffb9SDaniel Borkmann "data": { 87e254ffb9SDaniel Borkmann "mode": "l2", 88e254ffb9SDaniel Borkmann "pairing": "single", 89e254ffb9SDaniel Borkmann }, 90e254ffb9SDaniel Borkmann }, 91e254ffb9SDaniel Borkmann "num-rx-queues": rxqueues, 92e254ffb9SDaniel Borkmann }, 93e254ffb9SDaniel Borkmann flags=[Netlink.NLM_F_CREATE, Netlink.NLM_F_EXCL], 94e254ffb9SDaniel Borkmann ) 95e254ffb9SDaniel Borkmann 96e254ffb9SDaniel Borkmann all_links = ip("-d link show", json=True) 97e254ffb9SDaniel Borkmann nk_links = [ 98e254ffb9SDaniel Borkmann link 99e254ffb9SDaniel Borkmann for link in all_links 100e254ffb9SDaniel Borkmann if link.get("linkinfo", {}).get("info_kind") == "netkit" 101e254ffb9SDaniel Borkmann and "UP" not in link.get("flags", []) 102e254ffb9SDaniel Borkmann ] 103e254ffb9SDaniel Borkmann return nk_links[0]["ifname"], nk_links[0]["ifindex"] 104e254ffb9SDaniel Borkmann 105*1e822171SDaniel Borkmann 106e254ffb9SDaniel Borkmanndef test_remove_phys(netns) -> None: 107e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 108e254ffb9SDaniel Borkmann defer(nsimdev.remove) 109e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 110e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 111e254ffb9SDaniel Borkmann 112e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 113e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 114e254ffb9SDaniel Borkmann 115e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 116e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 117e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 118e254ffb9SDaniel Borkmann 119e254ffb9SDaniel Borkmann src_queue = 1 120e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 121e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 122e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 123e254ffb9SDaniel Borkmann { 124e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 125e254ffb9SDaniel Borkmann "type": "rx", 126e254ffb9SDaniel Borkmann "lease": { 127e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 128e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 129e254ffb9SDaniel Borkmann "netns-id": 0, 130e254ffb9SDaniel Borkmann }, 131e254ffb9SDaniel Borkmann } 132e254ffb9SDaniel Borkmann ) 133e254ffb9SDaniel Borkmann nk_queue_id = result["id"] 134e254ffb9SDaniel Borkmann 135e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 136e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 137e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 138e254ffb9SDaniel Borkmann ) 139e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 140e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["ifindex"], nk_guest_idx) 141e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 142e254ffb9SDaniel Borkmann 143e254ffb9SDaniel Borkmann nsimdev.remove() 144*1e822171SDaniel Borkmann wait_until(lambda: cmd(f"ip link show dev {nk_host}", fail=False).ret != 0) 145e254ffb9SDaniel Borkmann ret = cmd(f"ip link show dev {nk_host}", fail=False) 146e254ffb9SDaniel Borkmann ksft_ne(ret.ret, 0) 147e254ffb9SDaniel Borkmann 148e254ffb9SDaniel Borkmann 149e254ffb9SDaniel Borkmanndef test_double_lease(netns) -> None: 150e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 151e254ffb9SDaniel Borkmann defer(nsimdev.remove) 152e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 153e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 154e254ffb9SDaniel Borkmann 155e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=3) 156e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}") 157e254ffb9SDaniel Borkmann 158e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 159e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 160e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 161e254ffb9SDaniel Borkmann 162e254ffb9SDaniel Borkmann src_queue = 1 163e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 164e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 165e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 166e254ffb9SDaniel Borkmann { 167e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 168e254ffb9SDaniel Borkmann "type": "rx", 169e254ffb9SDaniel Borkmann "lease": { 170e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 171e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 172e254ffb9SDaniel Borkmann "netns-id": 0, 173e254ffb9SDaniel Borkmann }, 174e254ffb9SDaniel Borkmann } 175e254ffb9SDaniel Borkmann ) 176e254ffb9SDaniel Borkmann ksft_eq(result["id"], 1) 177e254ffb9SDaniel Borkmann 178e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 179e254ffb9SDaniel Borkmann netdevnl.queue_create( 180e254ffb9SDaniel Borkmann { 181e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 182e254ffb9SDaniel Borkmann "type": "rx", 183e254ffb9SDaniel Borkmann "lease": { 184e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 185e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 186e254ffb9SDaniel Borkmann "netns-id": 0, 187e254ffb9SDaniel Borkmann }, 188e254ffb9SDaniel Borkmann } 189e254ffb9SDaniel Borkmann ) 190e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EBUSY) 191e254ffb9SDaniel Borkmann 192e254ffb9SDaniel Borkmann 193e254ffb9SDaniel Borkmanndef test_virtual_lessor(netns) -> None: 194e254ffb9SDaniel Borkmann nk_host_a, _, nk_guest_a, nk_guest_a_idx = create_netkit(rxqueues=2) 195e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_a}") 196e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host_a} up") 197e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_a} up") 198e254ffb9SDaniel Borkmann 199e254ffb9SDaniel Borkmann nk_host_b, _, nk_guest_b, nk_guest_b_idx = create_netkit(rxqueues=2) 200e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_b}") 201e254ffb9SDaniel Borkmann 202e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_b} netns {netns.name}") 203e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host_b} up") 204e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_b} up", ns=netns) 205e254ffb9SDaniel Borkmann 206e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 207e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 208e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 209e254ffb9SDaniel Borkmann netdevnl.queue_create( 210e254ffb9SDaniel Borkmann { 211e254ffb9SDaniel Borkmann "ifindex": nk_guest_b_idx, 212e254ffb9SDaniel Borkmann "type": "rx", 213e254ffb9SDaniel Borkmann "lease": { 214e254ffb9SDaniel Borkmann "ifindex": nk_guest_a_idx, 215e254ffb9SDaniel Borkmann "queue": {"id": 0, "type": "rx"}, 216e254ffb9SDaniel Borkmann "netns-id": 0, 217e254ffb9SDaniel Borkmann }, 218e254ffb9SDaniel Borkmann } 219e254ffb9SDaniel Borkmann ) 220e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 221e254ffb9SDaniel Borkmann 222e254ffb9SDaniel Borkmann 223e254ffb9SDaniel Borkmanndef test_phys_lessee(_netns) -> None: 224e254ffb9SDaniel Borkmann nsimdev_a = NetdevSimDev(port_count=1, queue_count=2) 225e254ffb9SDaniel Borkmann defer(nsimdev_a.remove) 226e254ffb9SDaniel Borkmann nsim_a = nsimdev_a.nsims[0] 227e254ffb9SDaniel Borkmann ip(f"link set dev {nsim_a.ifname} up") 228e254ffb9SDaniel Borkmann 229e254ffb9SDaniel Borkmann nsimdev_b = NetdevSimDev(port_count=1, queue_count=2) 230e254ffb9SDaniel Borkmann defer(nsimdev_b.remove) 231e254ffb9SDaniel Borkmann nsim_b = nsimdev_b.nsims[0] 232e254ffb9SDaniel Borkmann ip(f"link set dev {nsim_b.ifname} up") 233e254ffb9SDaniel Borkmann 234e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 235e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 236e254ffb9SDaniel Borkmann netdevnl.queue_create( 237e254ffb9SDaniel Borkmann { 238e254ffb9SDaniel Borkmann "ifindex": nsim_a.ifindex, 239e254ffb9SDaniel Borkmann "type": "rx", 240e254ffb9SDaniel Borkmann "lease": { 241e254ffb9SDaniel Borkmann "ifindex": nsim_b.ifindex, 242e254ffb9SDaniel Borkmann "queue": {"id": 0, "type": "rx"}, 243e254ffb9SDaniel Borkmann }, 244e254ffb9SDaniel Borkmann } 245e254ffb9SDaniel Borkmann ) 246e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 247e254ffb9SDaniel Borkmann 248e254ffb9SDaniel Borkmann 249e254ffb9SDaniel Borkmanndef test_different_lessors(netns) -> None: 250e254ffb9SDaniel Borkmann nsimdev_a = NetdevSimDev(port_count=1, queue_count=2) 251e254ffb9SDaniel Borkmann defer(nsimdev_a.remove) 252e254ffb9SDaniel Borkmann nsim_a = nsimdev_a.nsims[0] 253e254ffb9SDaniel Borkmann ip(f"link set dev {nsim_a.ifname} up") 254e254ffb9SDaniel Borkmann 255e254ffb9SDaniel Borkmann nsimdev_b = NetdevSimDev(port_count=1, queue_count=2) 256e254ffb9SDaniel Borkmann defer(nsimdev_b.remove) 257e254ffb9SDaniel Borkmann nsim_b = nsimdev_b.nsims[0] 258e254ffb9SDaniel Borkmann ip(f"link set dev {nsim_b.ifname} up") 259e254ffb9SDaniel Borkmann 260e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=3) 261e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 262e254ffb9SDaniel Borkmann 263e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 264e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 265e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 266e254ffb9SDaniel Borkmann 267e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 268e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 269e254ffb9SDaniel Borkmann netdevnl.queue_create( 270e254ffb9SDaniel Borkmann { 271e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 272e254ffb9SDaniel Borkmann "type": "rx", 273e254ffb9SDaniel Borkmann "lease": { 274e254ffb9SDaniel Borkmann "ifindex": nsim_a.ifindex, 275e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 276e254ffb9SDaniel Borkmann "netns-id": 0, 277e254ffb9SDaniel Borkmann }, 278e254ffb9SDaniel Borkmann } 279e254ffb9SDaniel Borkmann ) 280e254ffb9SDaniel Borkmann 281e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 282e254ffb9SDaniel Borkmann netdevnl.queue_create( 283e254ffb9SDaniel Borkmann { 284e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 285e254ffb9SDaniel Borkmann "type": "rx", 286e254ffb9SDaniel Borkmann "lease": { 287e254ffb9SDaniel Borkmann "ifindex": nsim_b.ifindex, 288e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 289e254ffb9SDaniel Borkmann "netns-id": 0, 290e254ffb9SDaniel Borkmann }, 291e254ffb9SDaniel Borkmann } 292e254ffb9SDaniel Borkmann ) 293e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EOPNOTSUPP) 294e254ffb9SDaniel Borkmann 295e254ffb9SDaniel Borkmann 296e254ffb9SDaniel Borkmanndef test_queue_out_of_range(netns) -> None: 297e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 298e254ffb9SDaniel Borkmann defer(nsimdev.remove) 299e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 300e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 301e254ffb9SDaniel Borkmann 302e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 303e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 304e254ffb9SDaniel Borkmann 305e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 306e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 307e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 308e254ffb9SDaniel Borkmann 309e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 310e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 311e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 312e254ffb9SDaniel Borkmann netdevnl.queue_create( 313e254ffb9SDaniel Borkmann { 314e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 315e254ffb9SDaniel Borkmann "type": "rx", 316e254ffb9SDaniel Borkmann "lease": { 317e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 318e254ffb9SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 319e254ffb9SDaniel Borkmann "netns-id": 0, 320e254ffb9SDaniel Borkmann }, 321e254ffb9SDaniel Borkmann } 322e254ffb9SDaniel Borkmann ) 323e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.ERANGE) 324e254ffb9SDaniel Borkmann 325e254ffb9SDaniel Borkmann 326e254ffb9SDaniel Borkmanndef test_resize_leased(netns) -> None: 327e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 328e254ffb9SDaniel Borkmann defer(nsimdev.remove) 329e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 330e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 331e254ffb9SDaniel Borkmann 332e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 333e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 334e254ffb9SDaniel Borkmann 335e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 336e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 337e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 338e254ffb9SDaniel Borkmann 339e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 340e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 341e254ffb9SDaniel Borkmann netdevnl.queue_create( 342e254ffb9SDaniel Borkmann { 343e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 344e254ffb9SDaniel Borkmann "type": "rx", 345e254ffb9SDaniel Borkmann "lease": { 346e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 347e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 348e254ffb9SDaniel Borkmann "netns-id": 0, 349e254ffb9SDaniel Borkmann }, 350e254ffb9SDaniel Borkmann } 351e254ffb9SDaniel Borkmann ) 352e254ffb9SDaniel Borkmann 353e254ffb9SDaniel Borkmann ethnl = EthtoolFamily() 354e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 355e254ffb9SDaniel Borkmann ethnl.channels_set({"header": {"dev-index": nsim.ifindex}, "combined-count": 1}) 356e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 357e254ffb9SDaniel Borkmann 358e254ffb9SDaniel Borkmann 359e254ffb9SDaniel Borkmanndef test_self_lease(_netns) -> None: 360e254ffb9SDaniel Borkmann nk_host, _, _, nk_guest_idx = create_netkit(rxqueues=2) 361e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 362e254ffb9SDaniel Borkmann 363e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 364e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 365e254ffb9SDaniel Borkmann netdevnl.queue_create( 366e254ffb9SDaniel Borkmann { 367e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 368e254ffb9SDaniel Borkmann "type": "rx", 369e254ffb9SDaniel Borkmann "lease": { 370e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 371e254ffb9SDaniel Borkmann "queue": {"id": 0, "type": "rx"}, 372e254ffb9SDaniel Borkmann }, 373e254ffb9SDaniel Borkmann } 374e254ffb9SDaniel Borkmann ) 375e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 376e254ffb9SDaniel Borkmann 377e254ffb9SDaniel Borkmann 378e254ffb9SDaniel Borkmanndef test_veth_queue_create(netns) -> None: 379e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 380e254ffb9SDaniel Borkmann defer(nsimdev.remove) 381e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 382e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 383e254ffb9SDaniel Borkmann 384e254ffb9SDaniel Borkmann ip("link add veth0 type veth peer name veth1") 385e254ffb9SDaniel Borkmann defer(cmd, "ip link del dev veth0", fail=False) 386e254ffb9SDaniel Borkmann 387e254ffb9SDaniel Borkmann all_links = ip("-d link show", json=True) 388e254ffb9SDaniel Borkmann veth_peer = [ 389e254ffb9SDaniel Borkmann link 390e254ffb9SDaniel Borkmann for link in all_links 391e254ffb9SDaniel Borkmann if link.get("ifname") == "veth1" 392e254ffb9SDaniel Borkmann ] 393e254ffb9SDaniel Borkmann veth_peer_idx = veth_peer[0]["ifindex"] 394e254ffb9SDaniel Borkmann 395e254ffb9SDaniel Borkmann ip(f"link set dev veth1 netns {netns.name}") 396e254ffb9SDaniel Borkmann ip("link set dev veth0 up") 397e254ffb9SDaniel Borkmann ip("link set dev veth1 up", ns=netns) 398e254ffb9SDaniel Borkmann 399e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 400e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 401e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 402e254ffb9SDaniel Borkmann netdevnl.queue_create( 403e254ffb9SDaniel Borkmann { 404e254ffb9SDaniel Borkmann "ifindex": veth_peer_idx, 405e254ffb9SDaniel Borkmann "type": "rx", 406e254ffb9SDaniel Borkmann "lease": { 407e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 408e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 409e254ffb9SDaniel Borkmann "netns-id": 0, 410e254ffb9SDaniel Borkmann }, 411e254ffb9SDaniel Borkmann } 412e254ffb9SDaniel Borkmann ) 413e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 414e254ffb9SDaniel Borkmann 415e254ffb9SDaniel Borkmann 416e254ffb9SDaniel Borkmanndef test_create_tx_type(netns) -> None: 417e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 418e254ffb9SDaniel Borkmann defer(nsimdev.remove) 419e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 420e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 421e254ffb9SDaniel Borkmann 422e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 423e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 424e254ffb9SDaniel Borkmann 425e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 426e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 427e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 428e254ffb9SDaniel Borkmann 429e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 430e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 431e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 432e254ffb9SDaniel Borkmann netdevnl.queue_create( 433e254ffb9SDaniel Borkmann { 434e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 435e254ffb9SDaniel Borkmann "type": "tx", 436e254ffb9SDaniel Borkmann "lease": { 437e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 438e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 439e254ffb9SDaniel Borkmann "netns-id": 0, 440e254ffb9SDaniel Borkmann }, 441e254ffb9SDaniel Borkmann } 442e254ffb9SDaniel Borkmann ) 443e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 444e254ffb9SDaniel Borkmann 445e254ffb9SDaniel Borkmann 446e254ffb9SDaniel Borkmanndef test_create_primary(_netns) -> None: 447e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 448e254ffb9SDaniel Borkmann defer(nsimdev.remove) 449e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 450e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 451e254ffb9SDaniel Borkmann 452e254ffb9SDaniel Borkmann nk_host, nk_host_idx, _, _ = create_netkit(rxqueues=2) 453e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 454e254ffb9SDaniel Borkmann 455e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 456e254ffb9SDaniel Borkmann 457e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 458e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 459e254ffb9SDaniel Borkmann netdevnl.queue_create( 460e254ffb9SDaniel Borkmann { 461e254ffb9SDaniel Borkmann "ifindex": nk_host_idx, 462e254ffb9SDaniel Borkmann "type": "rx", 463e254ffb9SDaniel Borkmann "lease": { 464e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 465e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 466e254ffb9SDaniel Borkmann }, 467e254ffb9SDaniel Borkmann } 468e254ffb9SDaniel Borkmann ) 469e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EOPNOTSUPP) 470e254ffb9SDaniel Borkmann 471e254ffb9SDaniel Borkmann 472e254ffb9SDaniel Borkmanndef test_create_limit(netns) -> None: 473e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 474e254ffb9SDaniel Borkmann defer(nsimdev.remove) 475e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 476e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 477e254ffb9SDaniel Borkmann 478e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=1) 479e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 480e254ffb9SDaniel Borkmann 481e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 482e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 483e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 484e254ffb9SDaniel Borkmann 485e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 486e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 487e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 488e254ffb9SDaniel Borkmann netdevnl.queue_create( 489e254ffb9SDaniel Borkmann { 490e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 491e254ffb9SDaniel Borkmann "type": "rx", 492e254ffb9SDaniel Borkmann "lease": { 493e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 494e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 495e254ffb9SDaniel Borkmann "netns-id": 0, 496e254ffb9SDaniel Borkmann }, 497e254ffb9SDaniel Borkmann } 498e254ffb9SDaniel Borkmann ) 499e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 500e254ffb9SDaniel Borkmann 501e254ffb9SDaniel Borkmann 502e254ffb9SDaniel Borkmanndef test_link_flap_phys(netns) -> None: 503e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 504e254ffb9SDaniel Borkmann defer(nsimdev.remove) 505e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 506e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 507e254ffb9SDaniel Borkmann 508e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 509e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}") 510e254ffb9SDaniel Borkmann 511e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 512e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 513e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 514e254ffb9SDaniel Borkmann 515e254ffb9SDaniel Borkmann src_queue = 1 516e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 517e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 518e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 519e254ffb9SDaniel Borkmann { 520e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 521e254ffb9SDaniel Borkmann "type": "rx", 522e254ffb9SDaniel Borkmann "lease": { 523e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 524e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 525e254ffb9SDaniel Borkmann "netns-id": 0, 526e254ffb9SDaniel Borkmann }, 527e254ffb9SDaniel Borkmann } 528e254ffb9SDaniel Borkmann ) 529e254ffb9SDaniel Borkmann nk_queue_id = result["id"] 530e254ffb9SDaniel Borkmann 531e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 532e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 533e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 534e254ffb9SDaniel Borkmann ) 535e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 536e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 537e254ffb9SDaniel Borkmann 538e254ffb9SDaniel Borkmann # Link flap the physical device 539e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} down") 540e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 541e254ffb9SDaniel Borkmann 542e254ffb9SDaniel Borkmann # Verify lease survives the flap 543e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 544e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 545e254ffb9SDaniel Borkmann ) 546e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 547e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 548e254ffb9SDaniel Borkmann 549e254ffb9SDaniel Borkmann 550e254ffb9SDaniel Borkmanndef test_queue_get_virtual(netns) -> None: 551e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 552e254ffb9SDaniel Borkmann defer(nsimdev.remove) 553e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 554e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 555e254ffb9SDaniel Borkmann 556e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 557e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}") 558e254ffb9SDaniel Borkmann 559e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 560e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 561e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 562e254ffb9SDaniel Borkmann 563e254ffb9SDaniel Borkmann src_queue = 1 564e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 565e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 566e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 567e254ffb9SDaniel Borkmann { 568e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 569e254ffb9SDaniel Borkmann "type": "rx", 570e254ffb9SDaniel Borkmann "lease": { 571e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 572e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 573e254ffb9SDaniel Borkmann "netns-id": 0, 574e254ffb9SDaniel Borkmann }, 575e254ffb9SDaniel Borkmann } 576e254ffb9SDaniel Borkmann ) 577e254ffb9SDaniel Borkmann nk_queue_id = result["id"] 578e254ffb9SDaniel Borkmann 579e254ffb9SDaniel Borkmann # queue-get on virtual device's leased queue should not show lease 580e254ffb9SDaniel Borkmann # info (lease info is only shown from the physical device's side) 581e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 582e254ffb9SDaniel Borkmann {"ifindex": nk_guest_idx, "id": nk_queue_id, "type": "rx"} 583e254ffb9SDaniel Borkmann ) 584e254ffb9SDaniel Borkmann ksft_eq(queue_info["id"], nk_queue_id) 585e254ffb9SDaniel Borkmann ksft_eq(queue_info["ifindex"], nk_guest_idx) 586e254ffb9SDaniel Borkmann ksft_not_in("lease", queue_info) 587e254ffb9SDaniel Borkmann 588e254ffb9SDaniel Borkmann # Default queue (not leased) also has no lease info 589e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 590e254ffb9SDaniel Borkmann {"ifindex": nk_guest_idx, "id": 0, "type": "rx"} 591e254ffb9SDaniel Borkmann ) 592e254ffb9SDaniel Borkmann ksft_not_in("lease", queue_info) 593e254ffb9SDaniel Borkmann 594e254ffb9SDaniel Borkmann 595e254ffb9SDaniel Borkmanndef test_remove_virt_first(netns) -> None: 596e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 597e254ffb9SDaniel Borkmann defer(nsimdev.remove) 598e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 599e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 600e254ffb9SDaniel Borkmann 601e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 602e254ffb9SDaniel Borkmann 603e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 604e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 605e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 606e254ffb9SDaniel Borkmann 607e254ffb9SDaniel Borkmann src_queue = 1 608e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 609e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 610e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 611e254ffb9SDaniel Borkmann { 612e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 613e254ffb9SDaniel Borkmann "type": "rx", 614e254ffb9SDaniel Borkmann "lease": { 615e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 616e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 617e254ffb9SDaniel Borkmann "netns-id": 0, 618e254ffb9SDaniel Borkmann }, 619e254ffb9SDaniel Borkmann } 620e254ffb9SDaniel Borkmann ) 621e254ffb9SDaniel Borkmann ksft_eq(result["id"], 1) 622e254ffb9SDaniel Borkmann 623e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 624e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 625e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 626e254ffb9SDaniel Borkmann ) 627e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 628e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], result["id"]) 629e254ffb9SDaniel Borkmann 630e254ffb9SDaniel Borkmann # Delete netkit (virtual device removed first, physical stays) 631e254ffb9SDaniel Borkmann cmd(f"ip link del dev {nk_host}") 632e254ffb9SDaniel Borkmann 633e254ffb9SDaniel Borkmann # Verify lease is cleaned up on physical device 634e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 635e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 636e254ffb9SDaniel Borkmann ) 637e254ffb9SDaniel Borkmann ksft_not_in("lease", queue_info) 638e254ffb9SDaniel Borkmann 639e254ffb9SDaniel Borkmann 640e254ffb9SDaniel Borkmanndef test_multiple_leases(netns) -> None: 641e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=3) 642e254ffb9SDaniel Borkmann defer(nsimdev.remove) 643e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 644e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 645e254ffb9SDaniel Borkmann 646e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=4) 647e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 648e254ffb9SDaniel Borkmann 649e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 650e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 651e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 652e254ffb9SDaniel Borkmann 653e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 654e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 655e254ffb9SDaniel Borkmann r1 = netdevnl.queue_create( 656e254ffb9SDaniel Borkmann { 657e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 658e254ffb9SDaniel Borkmann "type": "rx", 659e254ffb9SDaniel Borkmann "lease": { 660e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 661e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 662e254ffb9SDaniel Borkmann "netns-id": 0, 663e254ffb9SDaniel Borkmann }, 664e254ffb9SDaniel Borkmann } 665e254ffb9SDaniel Borkmann ) 666e254ffb9SDaniel Borkmann r2 = netdevnl.queue_create( 667e254ffb9SDaniel Borkmann { 668e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 669e254ffb9SDaniel Borkmann "type": "rx", 670e254ffb9SDaniel Borkmann "lease": { 671e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 672e254ffb9SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 673e254ffb9SDaniel Borkmann "netns-id": 0, 674e254ffb9SDaniel Borkmann }, 675e254ffb9SDaniel Borkmann } 676e254ffb9SDaniel Borkmann ) 677e254ffb9SDaniel Borkmann 678e254ffb9SDaniel Borkmann ksft_eq(r1["id"], 1) 679e254ffb9SDaniel Borkmann ksft_eq(r2["id"], 2) 680e254ffb9SDaniel Borkmann 681e254ffb9SDaniel Borkmann # Verify both leases visible on physical device 682e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 683e254ffb9SDaniel Borkmann q1 = netdevnl.queue_get( 684e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 685e254ffb9SDaniel Borkmann ) 686e254ffb9SDaniel Borkmann q2 = netdevnl.queue_get( 687e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 688e254ffb9SDaniel Borkmann ) 689e254ffb9SDaniel Borkmann ksft_in("lease", q1) 690e254ffb9SDaniel Borkmann ksft_in("lease", q2) 691e254ffb9SDaniel Borkmann ksft_eq(q1["lease"]["ifindex"], nk_guest_idx) 692e254ffb9SDaniel Borkmann ksft_eq(q2["lease"]["ifindex"], nk_guest_idx) 693e254ffb9SDaniel Borkmann ksft_eq(q1["lease"]["queue"]["id"], r1["id"]) 694e254ffb9SDaniel Borkmann ksft_eq(q2["lease"]["queue"]["id"], r2["id"]) 695e254ffb9SDaniel Borkmann 696e254ffb9SDaniel Borkmann 697e254ffb9SDaniel Borkmanndef test_lease_queue_tx_type(netns) -> None: 698e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 699e254ffb9SDaniel Borkmann defer(nsimdev.remove) 700e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 701e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 702e254ffb9SDaniel Borkmann 703e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 704e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 705e254ffb9SDaniel Borkmann 706e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 707e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 708e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 709e254ffb9SDaniel Borkmann 710e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 711e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 712e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 713e254ffb9SDaniel Borkmann netdevnl.queue_create( 714e254ffb9SDaniel Borkmann { 715e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 716e254ffb9SDaniel Borkmann "type": "rx", 717e254ffb9SDaniel Borkmann "lease": { 718e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 719e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "tx"}, 720e254ffb9SDaniel Borkmann "netns-id": 0, 721e254ffb9SDaniel Borkmann }, 722e254ffb9SDaniel Borkmann } 723e254ffb9SDaniel Borkmann ) 724e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 725e254ffb9SDaniel Borkmann 726e254ffb9SDaniel Borkmann 727e254ffb9SDaniel Borkmanndef test_invalid_netns(netns) -> None: 728e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 729e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 730e254ffb9SDaniel Borkmann 731e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 732e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 733e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 734e254ffb9SDaniel Borkmann 735e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 736e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 737e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 738e254ffb9SDaniel Borkmann netdevnl.queue_create( 739e254ffb9SDaniel Borkmann { 740e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 741e254ffb9SDaniel Borkmann "type": "rx", 742e254ffb9SDaniel Borkmann "lease": { 743e254ffb9SDaniel Borkmann "ifindex": 1, 744e254ffb9SDaniel Borkmann "queue": {"id": 0, "type": "rx"}, 745e254ffb9SDaniel Borkmann "netns-id": 999, 746e254ffb9SDaniel Borkmann }, 747e254ffb9SDaniel Borkmann } 748e254ffb9SDaniel Borkmann ) 749e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.ENONET) 750e254ffb9SDaniel Borkmann 751e254ffb9SDaniel Borkmann 752e254ffb9SDaniel Borkmanndef test_invalid_phys_ifindex(netns) -> None: 753e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 754e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 755e254ffb9SDaniel Borkmann 756e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 757e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 758e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 759e254ffb9SDaniel Borkmann 760e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 761e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 762e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 763e254ffb9SDaniel Borkmann netdevnl.queue_create( 764e254ffb9SDaniel Borkmann { 765e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 766e254ffb9SDaniel Borkmann "type": "rx", 767e254ffb9SDaniel Borkmann "lease": { 768e254ffb9SDaniel Borkmann "ifindex": 99999, 769e254ffb9SDaniel Borkmann "queue": {"id": 0, "type": "rx"}, 770e254ffb9SDaniel Borkmann "netns-id": 0, 771e254ffb9SDaniel Borkmann }, 772e254ffb9SDaniel Borkmann } 773e254ffb9SDaniel Borkmann ) 774e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.ENODEV) 775e254ffb9SDaniel Borkmann 776e254ffb9SDaniel Borkmann 777e254ffb9SDaniel Borkmanndef test_multi_netkit_remove_phys(netns) -> None: 778e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=3) 779e254ffb9SDaniel Borkmann defer(nsimdev.remove) 780e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 781e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 782e254ffb9SDaniel Borkmann 783e254ffb9SDaniel Borkmann # Create two netkit pairs, each leasing a different physical queue 784e254ffb9SDaniel Borkmann nk_host_a, _, nk_guest_a, nk_guest_a_idx = create_netkit(rxqueues=2) 785e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_a}", fail=False) 786e254ffb9SDaniel Borkmann 787e254ffb9SDaniel Borkmann nk_host_b, _, nk_guest_b, nk_guest_b_idx = create_netkit(rxqueues=2) 788e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_b}", fail=False) 789e254ffb9SDaniel Borkmann 790e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_a} netns {netns.name}") 791e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host_a} up") 792e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_a} up", ns=netns) 793e254ffb9SDaniel Borkmann 794e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_b} netns {netns.name}") 795e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host_b} up") 796e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest_b} up", ns=netns) 797e254ffb9SDaniel Borkmann 798e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 799e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 800e254ffb9SDaniel Borkmann netdevnl.queue_create( 801e254ffb9SDaniel Borkmann { 802e254ffb9SDaniel Borkmann "ifindex": nk_guest_a_idx, 803e254ffb9SDaniel Borkmann "type": "rx", 804e254ffb9SDaniel Borkmann "lease": { 805e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 806e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 807e254ffb9SDaniel Borkmann "netns-id": 0, 808e254ffb9SDaniel Borkmann }, 809e254ffb9SDaniel Borkmann } 810e254ffb9SDaniel Borkmann ) 811e254ffb9SDaniel Borkmann netdevnl.queue_create( 812e254ffb9SDaniel Borkmann { 813e254ffb9SDaniel Borkmann "ifindex": nk_guest_b_idx, 814e254ffb9SDaniel Borkmann "type": "rx", 815e254ffb9SDaniel Borkmann "lease": { 816e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 817e254ffb9SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 818e254ffb9SDaniel Borkmann "netns-id": 0, 819e254ffb9SDaniel Borkmann }, 820e254ffb9SDaniel Borkmann } 821e254ffb9SDaniel Borkmann ) 822e254ffb9SDaniel Borkmann 823e254ffb9SDaniel Borkmann # Removing the physical device should take down both netkit pairs 824e254ffb9SDaniel Borkmann nsimdev.remove() 825*1e822171SDaniel Borkmann wait_until(lambda: cmd(f"ip link show dev {nk_host_a}", fail=False).ret != 0 826*1e822171SDaniel Borkmann and cmd(f"ip link show dev {nk_host_b}", fail=False).ret != 0) 827e254ffb9SDaniel Borkmann ret = cmd(f"ip link show dev {nk_host_a}", fail=False) 828e254ffb9SDaniel Borkmann ksft_ne(ret.ret, 0) 829e254ffb9SDaniel Borkmann ret = cmd(f"ip link show dev {nk_host_b}", fail=False) 830e254ffb9SDaniel Borkmann ksft_ne(ret.ret, 0) 831e254ffb9SDaniel Borkmann 832e254ffb9SDaniel Borkmann 833e254ffb9SDaniel Borkmanndef test_single_remove_phys(_netns) -> None: 834e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 835e254ffb9SDaniel Borkmann defer(nsimdev.remove) 836e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 837e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 838e254ffb9SDaniel Borkmann 839e254ffb9SDaniel Borkmann nk_name, nk_idx = create_netkit_single(rxqueues=2) 840e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_name}", fail=False) 841e254ffb9SDaniel Borkmann 842e254ffb9SDaniel Borkmann ip(f"link set dev {nk_name} up") 843e254ffb9SDaniel Borkmann 844e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 845e254ffb9SDaniel Borkmann netdevnl.queue_create( 846e254ffb9SDaniel Borkmann { 847e254ffb9SDaniel Borkmann "ifindex": nk_idx, 848e254ffb9SDaniel Borkmann "type": "rx", 849e254ffb9SDaniel Borkmann "lease": { 850e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 851e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 852e254ffb9SDaniel Borkmann }, 853e254ffb9SDaniel Borkmann } 854e254ffb9SDaniel Borkmann ) 855e254ffb9SDaniel Borkmann 856e254ffb9SDaniel Borkmann # Removing the physical device should take down the single netkit device 857e254ffb9SDaniel Borkmann nsimdev.remove() 858*1e822171SDaniel Borkmann wait_until(lambda: cmd(f"ip link show dev {nk_name}", fail=False).ret != 0) 859e254ffb9SDaniel Borkmann ret = cmd(f"ip link show dev {nk_name}", fail=False) 860e254ffb9SDaniel Borkmann ksft_ne(ret.ret, 0) 861e254ffb9SDaniel Borkmann 862e254ffb9SDaniel Borkmann 863e254ffb9SDaniel Borkmanndef test_link_flap_virt(netns) -> None: 864e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 865e254ffb9SDaniel Borkmann defer(nsimdev.remove) 866e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 867e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 868e254ffb9SDaniel Borkmann 869e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 870e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}") 871e254ffb9SDaniel Borkmann 872e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 873e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 874e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 875e254ffb9SDaniel Borkmann 876e254ffb9SDaniel Borkmann src_queue = 1 877e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 878e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 879e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 880e254ffb9SDaniel Borkmann { 881e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 882e254ffb9SDaniel Borkmann "type": "rx", 883e254ffb9SDaniel Borkmann "lease": { 884e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 885e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 886e254ffb9SDaniel Borkmann "netns-id": 0, 887e254ffb9SDaniel Borkmann }, 888e254ffb9SDaniel Borkmann } 889e254ffb9SDaniel Borkmann ) 890e254ffb9SDaniel Borkmann nk_queue_id = result["id"] 891e254ffb9SDaniel Borkmann 892e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 893e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 894e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 895e254ffb9SDaniel Borkmann ) 896e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 897e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 898e254ffb9SDaniel Borkmann 899e254ffb9SDaniel Borkmann # Link flap the virtual (netkit) device 900e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} down", ns=netns) 901e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 902e254ffb9SDaniel Borkmann 903e254ffb9SDaniel Borkmann # Verify lease survives the virtual device flap 904e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 905e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 906e254ffb9SDaniel Borkmann ) 907e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 908e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 909e254ffb9SDaniel Borkmann 910e254ffb9SDaniel Borkmann 911e254ffb9SDaniel Borkmanndef test_phys_queue_no_lease(netns) -> None: 912e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 913e254ffb9SDaniel Borkmann defer(nsimdev.remove) 914e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 915e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 916e254ffb9SDaniel Borkmann 917e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 918e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}") 919e254ffb9SDaniel Borkmann 920e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 921e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 922e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 923e254ffb9SDaniel Borkmann 924e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 925e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 926e254ffb9SDaniel Borkmann netdevnl.queue_create( 927e254ffb9SDaniel Borkmann { 928e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 929e254ffb9SDaniel Borkmann "type": "rx", 930e254ffb9SDaniel Borkmann "lease": { 931e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 932e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 933e254ffb9SDaniel Borkmann "netns-id": 0, 934e254ffb9SDaniel Borkmann }, 935e254ffb9SDaniel Borkmann } 936e254ffb9SDaniel Borkmann ) 937e254ffb9SDaniel Borkmann 938e254ffb9SDaniel Borkmann # Physical queue 0 (not leased) should have no lease info 939e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 940e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 941e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 0, "type": "rx"} 942e254ffb9SDaniel Borkmann ) 943e254ffb9SDaniel Borkmann ksft_not_in("lease", queue_info) 944e254ffb9SDaniel Borkmann 945e254ffb9SDaniel Borkmann # Physical queue 1 (leased) should have lease info 946e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 947e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 948e254ffb9SDaniel Borkmann ) 949e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 950e254ffb9SDaniel Borkmann 951e254ffb9SDaniel Borkmann 952e254ffb9SDaniel Borkmanndef test_same_ns_lease(_netns) -> None: 953e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 954e254ffb9SDaniel Borkmann defer(nsimdev.remove) 955e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 956e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 957e254ffb9SDaniel Borkmann 958e254ffb9SDaniel Borkmann nk_name, nk_idx = create_netkit_single(rxqueues=2) 959e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_name}", fail=False) 960e254ffb9SDaniel Borkmann 961e254ffb9SDaniel Borkmann ip(f"link set dev {nk_name} up") 962e254ffb9SDaniel Borkmann 963e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 964e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 965e254ffb9SDaniel Borkmann { 966e254ffb9SDaniel Borkmann "ifindex": nk_idx, 967e254ffb9SDaniel Borkmann "type": "rx", 968e254ffb9SDaniel Borkmann "lease": { 969e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 970e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 971e254ffb9SDaniel Borkmann }, 972e254ffb9SDaniel Borkmann } 973e254ffb9SDaniel Borkmann ) 974e254ffb9SDaniel Borkmann ksft_eq(result["id"], 1) 975e254ffb9SDaniel Borkmann 976e254ffb9SDaniel Borkmann # Same namespace: lease info should NOT have netns-id 977e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 978e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 979e254ffb9SDaniel Borkmann ) 980e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 981e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["ifindex"], nk_idx) 982e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], result["id"]) 983e254ffb9SDaniel Borkmann ksft_not_in("netns-id", queue_info["lease"]) 984e254ffb9SDaniel Borkmann 985e254ffb9SDaniel Borkmann 986e254ffb9SDaniel Borkmanndef test_resize_after_unlease(netns) -> None: 987e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 988e254ffb9SDaniel Borkmann defer(nsimdev.remove) 989e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 990e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 991e254ffb9SDaniel Borkmann 992e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 993e254ffb9SDaniel Borkmann 994e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 995e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 996e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 997e254ffb9SDaniel Borkmann 998e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 999e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1000e254ffb9SDaniel Borkmann netdevnl.queue_create( 1001e254ffb9SDaniel Borkmann { 1002e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 1003e254ffb9SDaniel Borkmann "type": "rx", 1004e254ffb9SDaniel Borkmann "lease": { 1005e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 1006e254ffb9SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1007e254ffb9SDaniel Borkmann "netns-id": 0, 1008e254ffb9SDaniel Borkmann }, 1009e254ffb9SDaniel Borkmann } 1010e254ffb9SDaniel Borkmann ) 1011e254ffb9SDaniel Borkmann 1012e254ffb9SDaniel Borkmann # Resize should fail while lease is active 1013e254ffb9SDaniel Borkmann ethnl = EthtoolFamily() 1014e254ffb9SDaniel Borkmann with ksft_raises(NlError) as e: 1015e254ffb9SDaniel Borkmann ethnl.channels_set({"header": {"dev-index": nsim.ifindex}, "combined-count": 1}) 1016e254ffb9SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 1017e254ffb9SDaniel Borkmann 1018e254ffb9SDaniel Borkmann # Delete netkit, clearing the lease 1019e254ffb9SDaniel Borkmann cmd(f"ip link del dev {nk_host}") 1020e254ffb9SDaniel Borkmann 1021e254ffb9SDaniel Borkmann # Resize should now succeed 1022e254ffb9SDaniel Borkmann ethnl.channels_set({"header": {"dev-index": nsim.ifindex}, "combined-count": 1}) 1023e254ffb9SDaniel Borkmann 1024e254ffb9SDaniel Borkmann 1025e254ffb9SDaniel Borkmanndef test_lease_queue_zero(netns) -> None: 1026e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1027e254ffb9SDaniel Borkmann defer(nsimdev.remove) 1028e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 1029e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1030e254ffb9SDaniel Borkmann 1031e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1032e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1033e254ffb9SDaniel Borkmann 1034e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1035e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 1036e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1037e254ffb9SDaniel Borkmann 1038e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 1039e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1040e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 1041e254ffb9SDaniel Borkmann { 1042e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 1043e254ffb9SDaniel Borkmann "type": "rx", 1044e254ffb9SDaniel Borkmann "lease": { 1045e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 1046e254ffb9SDaniel Borkmann "queue": {"id": 0, "type": "rx"}, 1047e254ffb9SDaniel Borkmann "netns-id": 0, 1048e254ffb9SDaniel Borkmann }, 1049e254ffb9SDaniel Borkmann } 1050e254ffb9SDaniel Borkmann ) 1051e254ffb9SDaniel Borkmann ksft_eq(result["id"], 1) 1052e254ffb9SDaniel Borkmann 1053e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1054e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 1055e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 0, "type": "rx"} 1056e254ffb9SDaniel Borkmann ) 1057e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 1058e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], result["id"]) 1059e254ffb9SDaniel Borkmann 1060e254ffb9SDaniel Borkmann 1061e254ffb9SDaniel Borkmanndef test_release_and_reuse(netns) -> None: 1062e254ffb9SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1063e254ffb9SDaniel Borkmann defer(nsimdev.remove) 1064e254ffb9SDaniel Borkmann nsim = nsimdev.nsims[0] 1065e254ffb9SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1066e254ffb9SDaniel Borkmann 1067e254ffb9SDaniel Borkmann src_queue = 1 1068e254ffb9SDaniel Borkmann 1069e254ffb9SDaniel Borkmann # First lease 1070e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1071e254ffb9SDaniel Borkmann 1072e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1073e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 1074e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1075e254ffb9SDaniel Borkmann 1076e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 1077e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1078e254ffb9SDaniel Borkmann netdevnl.queue_create( 1079e254ffb9SDaniel Borkmann { 1080e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 1081e254ffb9SDaniel Borkmann "type": "rx", 1082e254ffb9SDaniel Borkmann "lease": { 1083e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 1084e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1085e254ffb9SDaniel Borkmann "netns-id": 0, 1086e254ffb9SDaniel Borkmann }, 1087e254ffb9SDaniel Borkmann } 1088e254ffb9SDaniel Borkmann ) 1089e254ffb9SDaniel Borkmann 1090e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1091e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 1092e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1093e254ffb9SDaniel Borkmann ) 1094e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 1095e254ffb9SDaniel Borkmann 1096e254ffb9SDaniel Borkmann # Delete netkit, freeing the lease 1097e254ffb9SDaniel Borkmann cmd(f"ip link del dev {nk_host}") 1098e254ffb9SDaniel Borkmann 1099e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 1100e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1101e254ffb9SDaniel Borkmann ) 1102e254ffb9SDaniel Borkmann ksft_not_in("lease", queue_info) 1103e254ffb9SDaniel Borkmann 1104e254ffb9SDaniel Borkmann # Re-create netkit and lease the same physical queue again 1105e254ffb9SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1106e254ffb9SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1107e254ffb9SDaniel Borkmann 1108e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1109e254ffb9SDaniel Borkmann ip(f"link set dev {nk_host} up") 1110e254ffb9SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1111e254ffb9SDaniel Borkmann 1112e254ffb9SDaniel Borkmann with NetNSEnter(str(netns)): 1113e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1114e254ffb9SDaniel Borkmann result = netdevnl.queue_create( 1115e254ffb9SDaniel Borkmann { 1116e254ffb9SDaniel Borkmann "ifindex": nk_guest_idx, 1117e254ffb9SDaniel Borkmann "type": "rx", 1118e254ffb9SDaniel Borkmann "lease": { 1119e254ffb9SDaniel Borkmann "ifindex": nsim.ifindex, 1120e254ffb9SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1121e254ffb9SDaniel Borkmann "netns-id": 0, 1122e254ffb9SDaniel Borkmann }, 1123e254ffb9SDaniel Borkmann } 1124e254ffb9SDaniel Borkmann ) 1125e254ffb9SDaniel Borkmann ksft_eq(result["id"], 1) 1126e254ffb9SDaniel Borkmann 1127e254ffb9SDaniel Borkmann netdevnl = NetdevFamily() 1128e254ffb9SDaniel Borkmann queue_info = netdevnl.queue_get( 1129e254ffb9SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1130e254ffb9SDaniel Borkmann ) 1131e254ffb9SDaniel Borkmann ksft_in("lease", queue_info) 1132e254ffb9SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], result["id"]) 1133e254ffb9SDaniel Borkmann 1134e254ffb9SDaniel Borkmann 1135*1e822171SDaniel Borkmanndef test_two_netkits_same_queue(netns) -> None: 1136*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1137*1e822171SDaniel Borkmann defer(nsimdev.remove) 1138*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1139*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1140*1e822171SDaniel Borkmann 1141*1e822171SDaniel Borkmann nk_host_a, _, nk_guest_a, nk_guest_a_idx = create_netkit(rxqueues=2) 1142*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_a}", fail=False) 1143*1e822171SDaniel Borkmann 1144*1e822171SDaniel Borkmann nk_host_b, _, nk_guest_b, nk_guest_b_idx = create_netkit(rxqueues=2) 1145*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_b}", fail=False) 1146*1e822171SDaniel Borkmann 1147*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} netns {netns.name}") 1148*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_a} up") 1149*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} up", ns=netns) 1150*1e822171SDaniel Borkmann 1151*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} netns {netns.name}") 1152*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_b} up") 1153*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} up", ns=netns) 1154*1e822171SDaniel Borkmann 1155*1e822171SDaniel Borkmann src_queue = 1 1156*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1157*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1158*1e822171SDaniel Borkmann { 1159*1e822171SDaniel Borkmann "ifindex": nk_guest_a_idx, 1160*1e822171SDaniel Borkmann "type": "rx", 1161*1e822171SDaniel Borkmann "lease": { 1162*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1163*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1164*1e822171SDaniel Borkmann "netns-id": 0, 1165*1e822171SDaniel Borkmann }, 1166*1e822171SDaniel Borkmann } 1167*1e822171SDaniel Borkmann ) 1168*1e822171SDaniel Borkmann 1169*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1170*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1171*1e822171SDaniel Borkmann { 1172*1e822171SDaniel Borkmann "ifindex": nk_guest_b_idx, 1173*1e822171SDaniel Borkmann "type": "rx", 1174*1e822171SDaniel Borkmann "lease": { 1175*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1176*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1177*1e822171SDaniel Borkmann "netns-id": 0, 1178*1e822171SDaniel Borkmann }, 1179*1e822171SDaniel Borkmann } 1180*1e822171SDaniel Borkmann ) 1181*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EBUSY) 1182*1e822171SDaniel Borkmann 1183*1e822171SDaniel Borkmann 1184*1e822171SDaniel Borkmanndef test_l3_mode_lease(netns) -> None: 1185*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1186*1e822171SDaniel Borkmann defer(nsimdev.remove) 1187*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1188*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1189*1e822171SDaniel Borkmann 1190*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2, mode="l3") 1191*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1192*1e822171SDaniel Borkmann 1193*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1194*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1195*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1196*1e822171SDaniel Borkmann 1197*1e822171SDaniel Borkmann src_queue = 1 1198*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1199*1e822171SDaniel Borkmann result = netdevnl_ns.queue_create( 1200*1e822171SDaniel Borkmann { 1201*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1202*1e822171SDaniel Borkmann "type": "rx", 1203*1e822171SDaniel Borkmann "lease": { 1204*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1205*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1206*1e822171SDaniel Borkmann "netns-id": 0, 1207*1e822171SDaniel Borkmann }, 1208*1e822171SDaniel Borkmann } 1209*1e822171SDaniel Borkmann ) 1210*1e822171SDaniel Borkmann ksft_eq(result["id"], 1) 1211*1e822171SDaniel Borkmann 1212*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1213*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1214*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1215*1e822171SDaniel Borkmann ) 1216*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1217*1e822171SDaniel Borkmann ksft_eq(queue_info["lease"]["ifindex"], nk_guest_idx) 1218*1e822171SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], result["id"]) 1219*1e822171SDaniel Borkmann 1220*1e822171SDaniel Borkmann 1221*1e822171SDaniel Borkmanndef test_single_double_lease(_netns) -> None: 1222*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1223*1e822171SDaniel Borkmann defer(nsimdev.remove) 1224*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1225*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1226*1e822171SDaniel Borkmann 1227*1e822171SDaniel Borkmann nk_name, nk_idx = create_netkit_single(rxqueues=3) 1228*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_name}", fail=False) 1229*1e822171SDaniel Borkmann 1230*1e822171SDaniel Borkmann ip(f"link set dev {nk_name} up") 1231*1e822171SDaniel Borkmann 1232*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1233*1e822171SDaniel Borkmann result = netdevnl.queue_create( 1234*1e822171SDaniel Borkmann { 1235*1e822171SDaniel Borkmann "ifindex": nk_idx, 1236*1e822171SDaniel Borkmann "type": "rx", 1237*1e822171SDaniel Borkmann "lease": { 1238*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1239*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1240*1e822171SDaniel Borkmann }, 1241*1e822171SDaniel Borkmann } 1242*1e822171SDaniel Borkmann ) 1243*1e822171SDaniel Borkmann ksft_eq(result["id"], 1) 1244*1e822171SDaniel Borkmann 1245*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1246*1e822171SDaniel Borkmann netdevnl.queue_create( 1247*1e822171SDaniel Borkmann { 1248*1e822171SDaniel Borkmann "ifindex": nk_idx, 1249*1e822171SDaniel Borkmann "type": "rx", 1250*1e822171SDaniel Borkmann "lease": { 1251*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1252*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1253*1e822171SDaniel Borkmann }, 1254*1e822171SDaniel Borkmann } 1255*1e822171SDaniel Borkmann ) 1256*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EBUSY) 1257*1e822171SDaniel Borkmann 1258*1e822171SDaniel Borkmann 1259*1e822171SDaniel Borkmanndef test_single_different_lessors(_netns) -> None: 1260*1e822171SDaniel Borkmann nsimdev_a = NetdevSimDev(port_count=1, queue_count=2) 1261*1e822171SDaniel Borkmann defer(nsimdev_a.remove) 1262*1e822171SDaniel Borkmann nsim_a = nsimdev_a.nsims[0] 1263*1e822171SDaniel Borkmann ip(f"link set dev {nsim_a.ifname} up") 1264*1e822171SDaniel Borkmann 1265*1e822171SDaniel Borkmann nsimdev_b = NetdevSimDev(port_count=1, queue_count=2) 1266*1e822171SDaniel Borkmann defer(nsimdev_b.remove) 1267*1e822171SDaniel Borkmann nsim_b = nsimdev_b.nsims[0] 1268*1e822171SDaniel Borkmann ip(f"link set dev {nsim_b.ifname} up") 1269*1e822171SDaniel Borkmann 1270*1e822171SDaniel Borkmann nk_name, nk_idx = create_netkit_single(rxqueues=3) 1271*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_name}", fail=False) 1272*1e822171SDaniel Borkmann 1273*1e822171SDaniel Borkmann ip(f"link set dev {nk_name} up") 1274*1e822171SDaniel Borkmann 1275*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1276*1e822171SDaniel Borkmann netdevnl.queue_create( 1277*1e822171SDaniel Borkmann { 1278*1e822171SDaniel Borkmann "ifindex": nk_idx, 1279*1e822171SDaniel Borkmann "type": "rx", 1280*1e822171SDaniel Borkmann "lease": { 1281*1e822171SDaniel Borkmann "ifindex": nsim_a.ifindex, 1282*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1283*1e822171SDaniel Borkmann }, 1284*1e822171SDaniel Borkmann } 1285*1e822171SDaniel Borkmann ) 1286*1e822171SDaniel Borkmann 1287*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1288*1e822171SDaniel Borkmann netdevnl.queue_create( 1289*1e822171SDaniel Borkmann { 1290*1e822171SDaniel Borkmann "ifindex": nk_idx, 1291*1e822171SDaniel Borkmann "type": "rx", 1292*1e822171SDaniel Borkmann "lease": { 1293*1e822171SDaniel Borkmann "ifindex": nsim_b.ifindex, 1294*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1295*1e822171SDaniel Borkmann }, 1296*1e822171SDaniel Borkmann } 1297*1e822171SDaniel Borkmann ) 1298*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EOPNOTSUPP) 1299*1e822171SDaniel Borkmann 1300*1e822171SDaniel Borkmann 1301*1e822171SDaniel Borkmanndef test_cross_ns_netns_id(netns) -> None: 1302*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1303*1e822171SDaniel Borkmann defer(nsimdev.remove) 1304*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1305*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1306*1e822171SDaniel Borkmann 1307*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1308*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1309*1e822171SDaniel Borkmann 1310*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1311*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1312*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1313*1e822171SDaniel Borkmann 1314*1e822171SDaniel Borkmann src_queue = 1 1315*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1316*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1317*1e822171SDaniel Borkmann { 1318*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1319*1e822171SDaniel Borkmann "type": "rx", 1320*1e822171SDaniel Borkmann "lease": { 1321*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1322*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1323*1e822171SDaniel Borkmann "netns-id": 0, 1324*1e822171SDaniel Borkmann }, 1325*1e822171SDaniel Borkmann } 1326*1e822171SDaniel Borkmann ) 1327*1e822171SDaniel Borkmann 1328*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1329*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1330*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1331*1e822171SDaniel Borkmann ) 1332*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1333*1e822171SDaniel Borkmann ksft_in("netns-id", queue_info["lease"]) 1334*1e822171SDaniel Borkmann 1335*1e822171SDaniel Borkmann 1336*1e822171SDaniel Borkmanndef test_delete_guest_netns(_netns) -> None: 1337*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1338*1e822171SDaniel Borkmann defer(nsimdev.remove) 1339*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1340*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1341*1e822171SDaniel Borkmann 1342*1e822171SDaniel Borkmann test_ns = NetNS() 1343*1e822171SDaniel Borkmann ip("netns set init 0", ns=test_ns) 1344*1e822171SDaniel Borkmann ip("link set lo up", ns=test_ns) 1345*1e822171SDaniel Borkmann 1346*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1347*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1348*1e822171SDaniel Borkmann 1349*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {test_ns.name}") 1350*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1351*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=test_ns) 1352*1e822171SDaniel Borkmann 1353*1e822171SDaniel Borkmann src_queue = 1 1354*1e822171SDaniel Borkmann with NetNSEnter(str(test_ns)), NetdevFamily() as netdevnl_ns: 1355*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1356*1e822171SDaniel Borkmann { 1357*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1358*1e822171SDaniel Borkmann "type": "rx", 1359*1e822171SDaniel Borkmann "lease": { 1360*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1361*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1362*1e822171SDaniel Borkmann "netns-id": 0, 1363*1e822171SDaniel Borkmann }, 1364*1e822171SDaniel Borkmann } 1365*1e822171SDaniel Borkmann ) 1366*1e822171SDaniel Borkmann 1367*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1368*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1369*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1370*1e822171SDaniel Borkmann ) 1371*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1372*1e822171SDaniel Borkmann 1373*1e822171SDaniel Borkmann del test_ns 1374*1e822171SDaniel Borkmann wait_until(lambda: "lease" not in netdevnl.queue_get( 1375*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"})) 1376*1e822171SDaniel Borkmann 1377*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1378*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1379*1e822171SDaniel Borkmann ) 1380*1e822171SDaniel Borkmann ksft_not_in("lease", queue_info) 1381*1e822171SDaniel Borkmann 1382*1e822171SDaniel Borkmann ret = cmd(f"ip link show dev {nk_host}", fail=False) 1383*1e822171SDaniel Borkmann ksft_ne(ret.ret, 0) 1384*1e822171SDaniel Borkmann 1385*1e822171SDaniel Borkmann 1386*1e822171SDaniel Borkmanndef test_move_guest_netns(netns) -> None: 1387*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1388*1e822171SDaniel Borkmann defer(nsimdev.remove) 1389*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1390*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1391*1e822171SDaniel Borkmann 1392*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1393*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1394*1e822171SDaniel Borkmann 1395*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1396*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1397*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1398*1e822171SDaniel Borkmann 1399*1e822171SDaniel Borkmann src_queue = 1 1400*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1401*1e822171SDaniel Borkmann result = netdevnl_ns.queue_create( 1402*1e822171SDaniel Borkmann { 1403*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1404*1e822171SDaniel Borkmann "type": "rx", 1405*1e822171SDaniel Borkmann "lease": { 1406*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1407*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1408*1e822171SDaniel Borkmann "netns-id": 0, 1409*1e822171SDaniel Borkmann }, 1410*1e822171SDaniel Borkmann } 1411*1e822171SDaniel Borkmann ) 1412*1e822171SDaniel Borkmann nk_queue_id = result["id"] 1413*1e822171SDaniel Borkmann 1414*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1415*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1416*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1417*1e822171SDaniel Borkmann ) 1418*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1419*1e822171SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 1420*1e822171SDaniel Borkmann 1421*1e822171SDaniel Borkmann new_ns = NetNS() 1422*1e822171SDaniel Borkmann defer(new_ns.__del__) 1423*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {new_ns.name}", ns=netns) 1424*1e822171SDaniel Borkmann 1425*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1426*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1427*1e822171SDaniel Borkmann ) 1428*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1429*1e822171SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 1430*1e822171SDaniel Borkmann 1431*1e822171SDaniel Borkmann 1432*1e822171SDaniel Borkmanndef test_resize_phys_no_reduction(netns) -> None: 1433*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1434*1e822171SDaniel Borkmann defer(nsimdev.remove) 1435*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1436*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1437*1e822171SDaniel Borkmann 1438*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1439*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1440*1e822171SDaniel Borkmann 1441*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1442*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1443*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1444*1e822171SDaniel Borkmann 1445*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1446*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1447*1e822171SDaniel Borkmann { 1448*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1449*1e822171SDaniel Borkmann "type": "rx", 1450*1e822171SDaniel Borkmann "lease": { 1451*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1452*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1453*1e822171SDaniel Borkmann "netns-id": 0, 1454*1e822171SDaniel Borkmann }, 1455*1e822171SDaniel Borkmann } 1456*1e822171SDaniel Borkmann ) 1457*1e822171SDaniel Borkmann 1458*1e822171SDaniel Borkmann ethnl = EthtoolFamily() 1459*1e822171SDaniel Borkmann ethnl.channels_set( 1460*1e822171SDaniel Borkmann {"header": {"dev-index": nsim.ifindex}, "combined-count": 2} 1461*1e822171SDaniel Borkmann ) 1462*1e822171SDaniel Borkmann 1463*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1464*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1465*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1466*1e822171SDaniel Borkmann ) 1467*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1468*1e822171SDaniel Borkmann 1469*1e822171SDaniel Borkmann 1470*1e822171SDaniel Borkmanndef test_delete_one_netkit_of_two(netns) -> None: 1471*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=3) 1472*1e822171SDaniel Borkmann defer(nsimdev.remove) 1473*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1474*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1475*1e822171SDaniel Borkmann 1476*1e822171SDaniel Borkmann nk_host_a, _, nk_guest_a, nk_guest_a_idx = create_netkit(rxqueues=2) 1477*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_a}", fail=False) 1478*1e822171SDaniel Borkmann 1479*1e822171SDaniel Borkmann nk_host_b, _, nk_guest_b, nk_guest_b_idx = create_netkit(rxqueues=2) 1480*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_b}", fail=False) 1481*1e822171SDaniel Borkmann 1482*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} netns {netns.name}") 1483*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_a} up") 1484*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} up", ns=netns) 1485*1e822171SDaniel Borkmann 1486*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} netns {netns.name}") 1487*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_b} up") 1488*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} up", ns=netns) 1489*1e822171SDaniel Borkmann 1490*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1491*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1492*1e822171SDaniel Borkmann { 1493*1e822171SDaniel Borkmann "ifindex": nk_guest_a_idx, 1494*1e822171SDaniel Borkmann "type": "rx", 1495*1e822171SDaniel Borkmann "lease": { 1496*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1497*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1498*1e822171SDaniel Borkmann "netns-id": 0, 1499*1e822171SDaniel Borkmann }, 1500*1e822171SDaniel Borkmann } 1501*1e822171SDaniel Borkmann ) 1502*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1503*1e822171SDaniel Borkmann { 1504*1e822171SDaniel Borkmann "ifindex": nk_guest_b_idx, 1505*1e822171SDaniel Borkmann "type": "rx", 1506*1e822171SDaniel Borkmann "lease": { 1507*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1508*1e822171SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 1509*1e822171SDaniel Borkmann "netns-id": 0, 1510*1e822171SDaniel Borkmann }, 1511*1e822171SDaniel Borkmann } 1512*1e822171SDaniel Borkmann ) 1513*1e822171SDaniel Borkmann 1514*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1515*1e822171SDaniel Borkmann q1 = netdevnl.queue_get( 1516*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1517*1e822171SDaniel Borkmann ) 1518*1e822171SDaniel Borkmann q2 = netdevnl.queue_get( 1519*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1520*1e822171SDaniel Borkmann ) 1521*1e822171SDaniel Borkmann ksft_in("lease", q1) 1522*1e822171SDaniel Borkmann ksft_in("lease", q2) 1523*1e822171SDaniel Borkmann 1524*1e822171SDaniel Borkmann cmd(f"ip link del dev {nk_host_a}") 1525*1e822171SDaniel Borkmann 1526*1e822171SDaniel Borkmann q1 = netdevnl.queue_get( 1527*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1528*1e822171SDaniel Borkmann ) 1529*1e822171SDaniel Borkmann q2 = netdevnl.queue_get( 1530*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1531*1e822171SDaniel Borkmann ) 1532*1e822171SDaniel Borkmann ksft_not_in("lease", q1) 1533*1e822171SDaniel Borkmann ksft_in("lease", q2) 1534*1e822171SDaniel Borkmann 1535*1e822171SDaniel Borkmann 1536*1e822171SDaniel Borkmanndef test_bind_rx_leased_phys_queue(netns) -> None: 1537*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1538*1e822171SDaniel Borkmann defer(nsimdev.remove) 1539*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1540*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1541*1e822171SDaniel Borkmann 1542*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1543*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1544*1e822171SDaniel Borkmann 1545*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1546*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1547*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1548*1e822171SDaniel Borkmann 1549*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1550*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1551*1e822171SDaniel Borkmann { 1552*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1553*1e822171SDaniel Borkmann "type": "rx", 1554*1e822171SDaniel Borkmann "lease": { 1555*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1556*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1557*1e822171SDaniel Borkmann "netns-id": 0, 1558*1e822171SDaniel Borkmann }, 1559*1e822171SDaniel Borkmann } 1560*1e822171SDaniel Borkmann ) 1561*1e822171SDaniel Borkmann 1562*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1563*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1564*1e822171SDaniel Borkmann netdevnl.bind_rx( 1565*1e822171SDaniel Borkmann { 1566*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1567*1e822171SDaniel Borkmann "fd": 0, 1568*1e822171SDaniel Borkmann "queues": [ 1569*1e822171SDaniel Borkmann {"id": 0, "type": "rx"}, 1570*1e822171SDaniel Borkmann {"id": 1, "type": "rx"}, 1571*1e822171SDaniel Borkmann ], 1572*1e822171SDaniel Borkmann } 1573*1e822171SDaniel Borkmann ) 1574*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EOPNOTSUPP) 1575*1e822171SDaniel Borkmann 1576*1e822171SDaniel Borkmann 1577*1e822171SDaniel Borkmanndef test_resize_phys_shrink_past_leased(netns) -> None: 1578*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=4) 1579*1e822171SDaniel Borkmann defer(nsimdev.remove) 1580*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1581*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1582*1e822171SDaniel Borkmann 1583*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1584*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1585*1e822171SDaniel Borkmann 1586*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1587*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1588*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1589*1e822171SDaniel Borkmann 1590*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1591*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1592*1e822171SDaniel Borkmann { 1593*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1594*1e822171SDaniel Borkmann "type": "rx", 1595*1e822171SDaniel Borkmann "lease": { 1596*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1597*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1598*1e822171SDaniel Borkmann "netns-id": 0, 1599*1e822171SDaniel Borkmann }, 1600*1e822171SDaniel Borkmann } 1601*1e822171SDaniel Borkmann ) 1602*1e822171SDaniel Borkmann 1603*1e822171SDaniel Borkmann ethnl = EthtoolFamily() 1604*1e822171SDaniel Borkmann 1605*1e822171SDaniel Borkmann # Shrink past the leased queue — only queue 3 removed, queue 1 untouched 1606*1e822171SDaniel Borkmann ethnl.channels_set( 1607*1e822171SDaniel Borkmann {"header": {"dev-index": nsim.ifindex}, "combined-count": 3} 1608*1e822171SDaniel Borkmann ) 1609*1e822171SDaniel Borkmann 1610*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1611*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1612*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1613*1e822171SDaniel Borkmann ) 1614*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1615*1e822171SDaniel Borkmann 1616*1e822171SDaniel Borkmann # Shrink further — queue 2 removed, queue 1 still untouched 1617*1e822171SDaniel Borkmann ethnl.channels_set( 1618*1e822171SDaniel Borkmann {"header": {"dev-index": nsim.ifindex}, "combined-count": 2} 1619*1e822171SDaniel Borkmann ) 1620*1e822171SDaniel Borkmann 1621*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1622*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1623*1e822171SDaniel Borkmann ) 1624*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1625*1e822171SDaniel Borkmann 1626*1e822171SDaniel Borkmann # Shrink into the leased queue — queue 1 is busy, must fail 1627*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1628*1e822171SDaniel Borkmann ethnl.channels_set( 1629*1e822171SDaniel Borkmann {"header": {"dev-index": nsim.ifindex}, "combined-count": 1} 1630*1e822171SDaniel Borkmann ) 1631*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 1632*1e822171SDaniel Borkmann 1633*1e822171SDaniel Borkmann 1634*1e822171SDaniel Borkmanndef test_resize_virt_not_supported(netns) -> None: 1635*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1636*1e822171SDaniel Borkmann defer(nsimdev.remove) 1637*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1638*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1639*1e822171SDaniel Borkmann 1640*1e822171SDaniel Borkmann nk_host, nk_host_idx, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1641*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1642*1e822171SDaniel Borkmann 1643*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1644*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1645*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1646*1e822171SDaniel Borkmann 1647*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1648*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1649*1e822171SDaniel Borkmann { 1650*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1651*1e822171SDaniel Borkmann "type": "rx", 1652*1e822171SDaniel Borkmann "lease": { 1653*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1654*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1655*1e822171SDaniel Borkmann "netns-id": 0, 1656*1e822171SDaniel Borkmann }, 1657*1e822171SDaniel Borkmann } 1658*1e822171SDaniel Borkmann ) 1659*1e822171SDaniel Borkmann 1660*1e822171SDaniel Borkmann # Channel resize on the netkit host must fail — not supported 1661*1e822171SDaniel Borkmann ethnl = EthtoolFamily() 1662*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1663*1e822171SDaniel Borkmann ethnl.channels_set( 1664*1e822171SDaniel Borkmann {"header": {"dev-index": nk_host_idx}, "combined-count": 1} 1665*1e822171SDaniel Borkmann ) 1666*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EOPNOTSUPP) 1667*1e822171SDaniel Borkmann 1668*1e822171SDaniel Borkmann # Lease must be intact 1669*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1670*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1671*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1672*1e822171SDaniel Borkmann ) 1673*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1674*1e822171SDaniel Borkmann 1675*1e822171SDaniel Borkmann 1676*1e822171SDaniel Borkmanndef test_lease_devices_down(netns) -> None: 1677*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1678*1e822171SDaniel Borkmann defer(nsimdev.remove) 1679*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1680*1e822171SDaniel Borkmann 1681*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1682*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1683*1e822171SDaniel Borkmann 1684*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1685*1e822171SDaniel Borkmann 1686*1e822171SDaniel Borkmann # Create lease while both physical and virtual devices are down 1687*1e822171SDaniel Borkmann src_queue = 1 1688*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1689*1e822171SDaniel Borkmann result = netdevnl_ns.queue_create( 1690*1e822171SDaniel Borkmann { 1691*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1692*1e822171SDaniel Borkmann "type": "rx", 1693*1e822171SDaniel Borkmann "lease": { 1694*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1695*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 1696*1e822171SDaniel Borkmann "netns-id": 0, 1697*1e822171SDaniel Borkmann }, 1698*1e822171SDaniel Borkmann } 1699*1e822171SDaniel Borkmann ) 1700*1e822171SDaniel Borkmann ksft_eq(result["id"], 1) 1701*1e822171SDaniel Borkmann 1702*1e822171SDaniel Borkmann # Bring devices up before queue_get: netdevsim only instantiates NAPIs in 1703*1e822171SDaniel Borkmann # ndo_open, and netdev-genl queue_get returns -ENOENT without a NAPI. 1704*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1705*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1706*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1707*1e822171SDaniel Borkmann 1708*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1709*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1710*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 1711*1e822171SDaniel Borkmann ) 1712*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1713*1e822171SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], result["id"]) 1714*1e822171SDaniel Borkmann 1715*1e822171SDaniel Borkmann 1716*1e822171SDaniel Borkmanndef test_lease_capacity_exhaustion(netns) -> None: 1717*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=4) 1718*1e822171SDaniel Borkmann defer(nsimdev.remove) 1719*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1720*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1721*1e822171SDaniel Borkmann 1722*1e822171SDaniel Borkmann # rxqueues=3 means num_rx_queues=3, real_num_rx_queues starts at 1. 1723*1e822171SDaniel Borkmann # Can create 2 leased queues (real goes 1->2->3) but not a 3rd (3->4 > 3). 1724*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=3) 1725*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1726*1e822171SDaniel Borkmann 1727*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1728*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1729*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1730*1e822171SDaniel Borkmann 1731*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1732*1e822171SDaniel Borkmann r1 = netdevnl_ns.queue_create( 1733*1e822171SDaniel Borkmann { 1734*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1735*1e822171SDaniel Borkmann "type": "rx", 1736*1e822171SDaniel Borkmann "lease": { 1737*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1738*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1739*1e822171SDaniel Borkmann "netns-id": 0, 1740*1e822171SDaniel Borkmann }, 1741*1e822171SDaniel Borkmann } 1742*1e822171SDaniel Borkmann ) 1743*1e822171SDaniel Borkmann ksft_eq(r1["id"], 1) 1744*1e822171SDaniel Borkmann 1745*1e822171SDaniel Borkmann r2 = netdevnl_ns.queue_create( 1746*1e822171SDaniel Borkmann { 1747*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1748*1e822171SDaniel Borkmann "type": "rx", 1749*1e822171SDaniel Borkmann "lease": { 1750*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1751*1e822171SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 1752*1e822171SDaniel Borkmann "netns-id": 0, 1753*1e822171SDaniel Borkmann }, 1754*1e822171SDaniel Borkmann } 1755*1e822171SDaniel Borkmann ) 1756*1e822171SDaniel Borkmann ksft_eq(r2["id"], 2) 1757*1e822171SDaniel Borkmann 1758*1e822171SDaniel Borkmann # Third lease fails — netkit queue capacity exhausted 1759*1e822171SDaniel Borkmann with ksft_raises(NlError) as e: 1760*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1761*1e822171SDaniel Borkmann { 1762*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1763*1e822171SDaniel Borkmann "type": "rx", 1764*1e822171SDaniel Borkmann "lease": { 1765*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1766*1e822171SDaniel Borkmann "queue": {"id": 3, "type": "rx"}, 1767*1e822171SDaniel Borkmann "netns-id": 0, 1768*1e822171SDaniel Borkmann }, 1769*1e822171SDaniel Borkmann } 1770*1e822171SDaniel Borkmann ) 1771*1e822171SDaniel Borkmann ksft_eq(e.exception.nl_msg.error, -errno.EINVAL) 1772*1e822171SDaniel Borkmann 1773*1e822171SDaniel Borkmann # Verify the two successful leases are intact 1774*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1775*1e822171SDaniel Borkmann q1 = netdevnl.queue_get( 1776*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1777*1e822171SDaniel Borkmann ) 1778*1e822171SDaniel Borkmann q2 = netdevnl.queue_get( 1779*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1780*1e822171SDaniel Borkmann ) 1781*1e822171SDaniel Borkmann ksft_in("lease", q1) 1782*1e822171SDaniel Borkmann ksft_in("lease", q2) 1783*1e822171SDaniel Borkmann 1784*1e822171SDaniel Borkmann 1785*1e822171SDaniel Borkmanndef test_resize_phys_up(netns) -> None: 1786*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=3) 1787*1e822171SDaniel Borkmann defer(nsimdev.remove) 1788*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1789*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1790*1e822171SDaniel Borkmann 1791*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1792*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1793*1e822171SDaniel Borkmann 1794*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1795*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1796*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 1797*1e822171SDaniel Borkmann 1798*1e822171SDaniel Borkmann # Shrink nsim first so we have room to grow 1799*1e822171SDaniel Borkmann ethnl = EthtoolFamily() 1800*1e822171SDaniel Borkmann ethnl.channels_set( 1801*1e822171SDaniel Borkmann {"header": {"dev-index": nsim.ifindex}, "combined-count": 2} 1802*1e822171SDaniel Borkmann ) 1803*1e822171SDaniel Borkmann 1804*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1805*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1806*1e822171SDaniel Borkmann { 1807*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 1808*1e822171SDaniel Borkmann "type": "rx", 1809*1e822171SDaniel Borkmann "lease": { 1810*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1811*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1812*1e822171SDaniel Borkmann "netns-id": 0, 1813*1e822171SDaniel Borkmann }, 1814*1e822171SDaniel Borkmann } 1815*1e822171SDaniel Borkmann ) 1816*1e822171SDaniel Borkmann 1817*1e822171SDaniel Borkmann # Grow channels — should succeed since leased queue is not removed 1818*1e822171SDaniel Borkmann ethnl.channels_set( 1819*1e822171SDaniel Borkmann {"header": {"dev-index": nsim.ifindex}, "combined-count": 3} 1820*1e822171SDaniel Borkmann ) 1821*1e822171SDaniel Borkmann 1822*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1823*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1824*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1825*1e822171SDaniel Borkmann ) 1826*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 1827*1e822171SDaniel Borkmann 1828*1e822171SDaniel Borkmann # New queue 2 should exist without a lease 1829*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 1830*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1831*1e822171SDaniel Borkmann ) 1832*1e822171SDaniel Borkmann ksft_not_in("lease", queue_info) 1833*1e822171SDaniel Borkmann 1834*1e822171SDaniel Borkmann 1835*1e822171SDaniel Borkmanndef test_multi_ns_lease(netns) -> None: 1836*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=3) 1837*1e822171SDaniel Borkmann defer(nsimdev.remove) 1838*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1839*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1840*1e822171SDaniel Borkmann 1841*1e822171SDaniel Borkmann ns_b = NetNS() 1842*1e822171SDaniel Borkmann defer(ns_b.__del__) 1843*1e822171SDaniel Borkmann ip("netns set init 0", ns=ns_b) 1844*1e822171SDaniel Borkmann ip("link set lo up", ns=ns_b) 1845*1e822171SDaniel Borkmann 1846*1e822171SDaniel Borkmann # First netkit pair, guest in netns 1847*1e822171SDaniel Borkmann nk_host_a, _, nk_guest_a, nk_guest_a_idx = create_netkit(rxqueues=2) 1848*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_a}", fail=False) 1849*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} netns {netns.name}") 1850*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_a} up") 1851*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} up", ns=netns) 1852*1e822171SDaniel Borkmann 1853*1e822171SDaniel Borkmann # Second netkit pair, guest in ns_b 1854*1e822171SDaniel Borkmann nk_host_b, _, nk_guest_b, nk_guest_b_idx = create_netkit(rxqueues=2) 1855*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_b}", fail=False) 1856*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} netns {ns_b.name}") 1857*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_b} up") 1858*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} up", ns=ns_b) 1859*1e822171SDaniel Borkmann 1860*1e822171SDaniel Borkmann # Lease from netns 1861*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1862*1e822171SDaniel Borkmann result = netdevnl_ns.queue_create( 1863*1e822171SDaniel Borkmann { 1864*1e822171SDaniel Borkmann "ifindex": nk_guest_a_idx, 1865*1e822171SDaniel Borkmann "type": "rx", 1866*1e822171SDaniel Borkmann "lease": { 1867*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1868*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1869*1e822171SDaniel Borkmann "netns-id": 0, 1870*1e822171SDaniel Borkmann }, 1871*1e822171SDaniel Borkmann } 1872*1e822171SDaniel Borkmann ) 1873*1e822171SDaniel Borkmann ksft_eq(result["id"], 1) 1874*1e822171SDaniel Borkmann 1875*1e822171SDaniel Borkmann # Lease from ns_b (different namespace, same physical device) 1876*1e822171SDaniel Borkmann with NetNSEnter(str(ns_b)), NetdevFamily() as netdevnl_ns: 1877*1e822171SDaniel Borkmann result = netdevnl_ns.queue_create( 1878*1e822171SDaniel Borkmann { 1879*1e822171SDaniel Borkmann "ifindex": nk_guest_b_idx, 1880*1e822171SDaniel Borkmann "type": "rx", 1881*1e822171SDaniel Borkmann "lease": { 1882*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1883*1e822171SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 1884*1e822171SDaniel Borkmann "netns-id": 0, 1885*1e822171SDaniel Borkmann }, 1886*1e822171SDaniel Borkmann } 1887*1e822171SDaniel Borkmann ) 1888*1e822171SDaniel Borkmann ksft_eq(result["id"], 1) 1889*1e822171SDaniel Borkmann 1890*1e822171SDaniel Borkmann # Verify both leases from the physical side 1891*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1892*1e822171SDaniel Borkmann q1 = netdevnl.queue_get( 1893*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1894*1e822171SDaniel Borkmann ) 1895*1e822171SDaniel Borkmann q2 = netdevnl.queue_get( 1896*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1897*1e822171SDaniel Borkmann ) 1898*1e822171SDaniel Borkmann ksft_in("lease", q1) 1899*1e822171SDaniel Borkmann ksft_in("lease", q2) 1900*1e822171SDaniel Borkmann ksft_eq(q1["lease"]["ifindex"], nk_guest_a_idx) 1901*1e822171SDaniel Borkmann ksft_eq(q2["lease"]["ifindex"], nk_guest_b_idx) 1902*1e822171SDaniel Borkmann 1903*1e822171SDaniel Borkmann 1904*1e822171SDaniel Borkmanndef test_multi_ns_delete_one(netns) -> None: 1905*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=3) 1906*1e822171SDaniel Borkmann defer(nsimdev.remove) 1907*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1908*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1909*1e822171SDaniel Borkmann 1910*1e822171SDaniel Borkmann ns_b = NetNS() 1911*1e822171SDaniel Borkmann ip("netns set init 0", ns=ns_b) 1912*1e822171SDaniel Borkmann ip("link set lo up", ns=ns_b) 1913*1e822171SDaniel Borkmann 1914*1e822171SDaniel Borkmann # First netkit pair, guest in netns (ns_a) 1915*1e822171SDaniel Borkmann nk_host_a, _, nk_guest_a, nk_guest_a_idx = create_netkit(rxqueues=2) 1916*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_a}", fail=False) 1917*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} netns {netns.name}") 1918*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_a} up") 1919*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_a} up", ns=netns) 1920*1e822171SDaniel Borkmann 1921*1e822171SDaniel Borkmann # Second netkit pair, guest in ns_b 1922*1e822171SDaniel Borkmann nk_host_b, _, nk_guest_b, nk_guest_b_idx = create_netkit(rxqueues=2) 1923*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host_b}", fail=False) 1924*1e822171SDaniel Borkmann 1925*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} netns {ns_b.name}") 1926*1e822171SDaniel Borkmann ip(f"link set dev {nk_host_b} up") 1927*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest_b} up", ns=ns_b) 1928*1e822171SDaniel Borkmann 1929*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 1930*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1931*1e822171SDaniel Borkmann { 1932*1e822171SDaniel Borkmann "ifindex": nk_guest_a_idx, 1933*1e822171SDaniel Borkmann "type": "rx", 1934*1e822171SDaniel Borkmann "lease": { 1935*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1936*1e822171SDaniel Borkmann "queue": {"id": 1, "type": "rx"}, 1937*1e822171SDaniel Borkmann "netns-id": 0, 1938*1e822171SDaniel Borkmann }, 1939*1e822171SDaniel Borkmann } 1940*1e822171SDaniel Borkmann ) 1941*1e822171SDaniel Borkmann 1942*1e822171SDaniel Borkmann with NetNSEnter(str(ns_b)), NetdevFamily() as netdevnl_ns: 1943*1e822171SDaniel Borkmann netdevnl_ns.queue_create( 1944*1e822171SDaniel Borkmann { 1945*1e822171SDaniel Borkmann "ifindex": nk_guest_b_idx, 1946*1e822171SDaniel Borkmann "type": "rx", 1947*1e822171SDaniel Borkmann "lease": { 1948*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 1949*1e822171SDaniel Borkmann "queue": {"id": 2, "type": "rx"}, 1950*1e822171SDaniel Borkmann "netns-id": 0, 1951*1e822171SDaniel Borkmann }, 1952*1e822171SDaniel Borkmann } 1953*1e822171SDaniel Borkmann ) 1954*1e822171SDaniel Borkmann 1955*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 1956*1e822171SDaniel Borkmann q1 = netdevnl.queue_get( 1957*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1958*1e822171SDaniel Borkmann ) 1959*1e822171SDaniel Borkmann q2 = netdevnl.queue_get( 1960*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1961*1e822171SDaniel Borkmann ) 1962*1e822171SDaniel Borkmann ksft_in("lease", q1) 1963*1e822171SDaniel Borkmann ksft_in("lease", q2) 1964*1e822171SDaniel Borkmann 1965*1e822171SDaniel Borkmann # Delete ns_b — destroys nk_guest_b, triggers unlease of queue 2 1966*1e822171SDaniel Borkmann del ns_b 1967*1e822171SDaniel Borkmann wait_until(lambda: "lease" not in netdevnl.queue_get( 1968*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"})) 1969*1e822171SDaniel Borkmann 1970*1e822171SDaniel Borkmann # ns_a's lease on queue 1 must survive 1971*1e822171SDaniel Borkmann q1 = netdevnl.queue_get( 1972*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 1, "type": "rx"} 1973*1e822171SDaniel Borkmann ) 1974*1e822171SDaniel Borkmann ksft_in("lease", q1) 1975*1e822171SDaniel Borkmann ksft_eq(q1["lease"]["ifindex"], nk_guest_a_idx) 1976*1e822171SDaniel Borkmann 1977*1e822171SDaniel Borkmann # ns_b's lease on queue 2 must be gone 1978*1e822171SDaniel Borkmann q2 = netdevnl.queue_get( 1979*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": 2, "type": "rx"} 1980*1e822171SDaniel Borkmann ) 1981*1e822171SDaniel Borkmann ksft_not_in("lease", q2) 1982*1e822171SDaniel Borkmann 1983*1e822171SDaniel Borkmann # nk_host_b should be gone too (phys removal cascades to netkit pair) 1984*1e822171SDaniel Borkmann ret = cmd(f"ip link show dev {nk_host_b}", fail=False) 1985*1e822171SDaniel Borkmann ksft_ne(ret.ret, 0) 1986*1e822171SDaniel Borkmann 1987*1e822171SDaniel Borkmann 1988*1e822171SDaniel Borkmanndef test_move_phys_netns(netns) -> None: 1989*1e822171SDaniel Borkmann nsimdev = NetdevSimDev(port_count=1, queue_count=2) 1990*1e822171SDaniel Borkmann defer(nsimdev.remove) 1991*1e822171SDaniel Borkmann nsim = nsimdev.nsims[0] 1992*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up") 1993*1e822171SDaniel Borkmann 1994*1e822171SDaniel Borkmann nk_host, _, nk_guest, nk_guest_idx = create_netkit(rxqueues=2) 1995*1e822171SDaniel Borkmann defer(cmd, f"ip link del dev {nk_host}", fail=False) 1996*1e822171SDaniel Borkmann 1997*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} netns {netns.name}") 1998*1e822171SDaniel Borkmann ip(f"link set dev {nk_host} up") 1999*1e822171SDaniel Borkmann ip(f"link set dev {nk_guest} up", ns=netns) 2000*1e822171SDaniel Borkmann 2001*1e822171SDaniel Borkmann src_queue = 1 2002*1e822171SDaniel Borkmann with NetNSEnter(str(netns)), NetdevFamily() as netdevnl_ns: 2003*1e822171SDaniel Borkmann nk_queue_id = netdevnl_ns.queue_create( 2004*1e822171SDaniel Borkmann { 2005*1e822171SDaniel Borkmann "ifindex": nk_guest_idx, 2006*1e822171SDaniel Borkmann "type": "rx", 2007*1e822171SDaniel Borkmann "lease": { 2008*1e822171SDaniel Borkmann "ifindex": nsim.ifindex, 2009*1e822171SDaniel Borkmann "queue": {"id": src_queue, "type": "rx"}, 2010*1e822171SDaniel Borkmann "netns-id": 0, 2011*1e822171SDaniel Borkmann }, 2012*1e822171SDaniel Borkmann } 2013*1e822171SDaniel Borkmann )["id"] 2014*1e822171SDaniel Borkmann 2015*1e822171SDaniel Borkmann netdevnl = NetdevFamily() 2016*1e822171SDaniel Borkmann queue_info = netdevnl.queue_get( 2017*1e822171SDaniel Borkmann {"ifindex": nsim.ifindex, "id": src_queue, "type": "rx"} 2018*1e822171SDaniel Borkmann ) 2019*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 2020*1e822171SDaniel Borkmann 2021*1e822171SDaniel Borkmann # Move the physical device to a new namespace. Move it back to init_net 2022*1e822171SDaniel Borkmann # on cleanup before the other defers fire (new_ns deletion, nsimdev.remove) 2023*1e822171SDaniel Borkmann # so nsim lives in a stable namespace when they run. 2024*1e822171SDaniel Borkmann new_ns = NetNS() 2025*1e822171SDaniel Borkmann defer(new_ns.__del__) 2026*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} netns {new_ns.name}") 2027*1e822171SDaniel Borkmann defer(ip, f"link set dev {nsim.ifname} netns init", ns=new_ns) 2028*1e822171SDaniel Borkmann 2029*1e822171SDaniel Borkmann # Physical device is now in new_ns — find its ifindex there 2030*1e822171SDaniel Borkmann all_links = ip("-d link show", json=True, ns=new_ns) 2031*1e822171SDaniel Borkmann nsim_in_new = [lnk for lnk in all_links if lnk.get("ifname") == nsim.ifname] 2032*1e822171SDaniel Borkmann new_ifindex = nsim_in_new[0]["ifindex"] 2033*1e822171SDaniel Borkmann 2034*1e822171SDaniel Borkmann # Moving a device across netns brings it admin-down; bring it back up so 2035*1e822171SDaniel Borkmann # netdevsim re-creates the NAPI (netdev-genl queue_get needs it). 2036*1e822171SDaniel Borkmann ip(f"link set dev {nsim.ifname} up", ns=new_ns) 2037*1e822171SDaniel Borkmann 2038*1e822171SDaniel Borkmann # Verify lease survived the namespace move 2039*1e822171SDaniel Borkmann with NetNSEnter(str(new_ns)), NetdevFamily() as netdevnl_ns: 2040*1e822171SDaniel Borkmann queue_info = netdevnl_ns.queue_get( 2041*1e822171SDaniel Borkmann {"ifindex": new_ifindex, "id": src_queue, "type": "rx"} 2042*1e822171SDaniel Borkmann ) 2043*1e822171SDaniel Borkmann ksft_in("lease", queue_info) 2044*1e822171SDaniel Borkmann ksft_eq(queue_info["lease"]["queue"]["id"], nk_queue_id) 2045*1e822171SDaniel Borkmann 2046*1e822171SDaniel Borkmann 2047e254ffb9SDaniel Borkmanndef main() -> None: 2048e254ffb9SDaniel Borkmann netns = NetNS() 2049e254ffb9SDaniel Borkmann cmd("ip netns attach init 1") 2050e254ffb9SDaniel Borkmann ip("netns set init 0", ns=netns) 2051e254ffb9SDaniel Borkmann ip("link set lo up", ns=netns) 2052e254ffb9SDaniel Borkmann 2053e254ffb9SDaniel Borkmann ksft_run( 2054e254ffb9SDaniel Borkmann [ 2055e254ffb9SDaniel Borkmann test_remove_phys, 2056e254ffb9SDaniel Borkmann test_double_lease, 2057e254ffb9SDaniel Borkmann test_virtual_lessor, 2058e254ffb9SDaniel Borkmann test_phys_lessee, 2059e254ffb9SDaniel Borkmann test_different_lessors, 2060e254ffb9SDaniel Borkmann test_queue_out_of_range, 2061e254ffb9SDaniel Borkmann test_resize_leased, 2062e254ffb9SDaniel Borkmann test_self_lease, 2063e254ffb9SDaniel Borkmann test_create_tx_type, 2064e254ffb9SDaniel Borkmann test_create_primary, 2065e254ffb9SDaniel Borkmann test_create_limit, 2066e254ffb9SDaniel Borkmann test_link_flap_phys, 2067e254ffb9SDaniel Borkmann test_queue_get_virtual, 2068e254ffb9SDaniel Borkmann test_remove_virt_first, 2069e254ffb9SDaniel Borkmann test_multiple_leases, 2070e254ffb9SDaniel Borkmann test_lease_queue_tx_type, 2071e254ffb9SDaniel Borkmann test_invalid_netns, 2072e254ffb9SDaniel Borkmann test_invalid_phys_ifindex, 2073e254ffb9SDaniel Borkmann test_multi_netkit_remove_phys, 2074e254ffb9SDaniel Borkmann test_single_remove_phys, 2075e254ffb9SDaniel Borkmann test_link_flap_virt, 2076e254ffb9SDaniel Borkmann test_phys_queue_no_lease, 2077e254ffb9SDaniel Borkmann test_same_ns_lease, 2078e254ffb9SDaniel Borkmann test_resize_after_unlease, 2079e254ffb9SDaniel Borkmann test_lease_queue_zero, 2080e254ffb9SDaniel Borkmann test_release_and_reuse, 2081e254ffb9SDaniel Borkmann test_veth_queue_create, 2082*1e822171SDaniel Borkmann test_two_netkits_same_queue, 2083*1e822171SDaniel Borkmann test_l3_mode_lease, 2084*1e822171SDaniel Borkmann test_single_double_lease, 2085*1e822171SDaniel Borkmann test_single_different_lessors, 2086*1e822171SDaniel Borkmann test_cross_ns_netns_id, 2087*1e822171SDaniel Borkmann test_delete_guest_netns, 2088*1e822171SDaniel Borkmann test_move_guest_netns, 2089*1e822171SDaniel Borkmann test_resize_phys_no_reduction, 2090*1e822171SDaniel Borkmann test_delete_one_netkit_of_two, 2091*1e822171SDaniel Borkmann test_bind_rx_leased_phys_queue, 2092*1e822171SDaniel Borkmann test_resize_phys_shrink_past_leased, 2093*1e822171SDaniel Borkmann test_resize_virt_not_supported, 2094*1e822171SDaniel Borkmann test_lease_devices_down, 2095*1e822171SDaniel Borkmann test_lease_capacity_exhaustion, 2096*1e822171SDaniel Borkmann test_resize_phys_up, 2097*1e822171SDaniel Borkmann test_multi_ns_lease, 2098*1e822171SDaniel Borkmann test_multi_ns_delete_one, 2099*1e822171SDaniel Borkmann test_move_phys_netns, 2100e254ffb9SDaniel Borkmann ], 2101e254ffb9SDaniel Borkmann args=(netns,), 2102e254ffb9SDaniel Borkmann ) 2103e254ffb9SDaniel Borkmann 2104e254ffb9SDaniel Borkmann cmd("ip netns del init", fail=False) 2105e254ffb9SDaniel Borkmann ksft_exit() 2106e254ffb9SDaniel Borkmann 2107e254ffb9SDaniel Borkmann 2108e254ffb9SDaniel Borkmannif __name__ == "__main__": 2109e254ffb9SDaniel Borkmann main() 2110