Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 204 lines 7.4 kB view raw
1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0 3"""Traffic test for VXLAN + IPsec crypto-offload.""" 4 5import os 6 7from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_ge 8from lib.py import ksft_variants, KsftNamedVariant, KsftSkipEx 9from lib.py import CmdExitFailure, NetDrvEpEnv, cmd, defer, ethtool, ip 10from lib.py import Iperf3Runner 11 12# Inner tunnel addresses - TEST-NET-2 (RFC 5737) / doc prefix (RFC 3849) 13INNER_V4_LOCAL = "198.51.100.1" 14INNER_V4_REMOTE = "198.51.100.2" 15INNER_V6_LOCAL = "2001:db8:100::1" 16INNER_V6_REMOTE = "2001:db8:100::2" 17 18# ESP parameters 19SPI_OUT = "0x1000" 20SPI_IN = "0x1001" 21# 128-bit key + 32-bit salt = 20 bytes hex, 128-bit ICV 22ESP_AEAD = "aead 'rfc4106(gcm(aes))' 0x" + "01" * 20 + " 128" 23 24 25def xfrm(args, host=None): 26 """Runs 'ip xfrm' via shell to preserve parentheses in algo names.""" 27 cmd(f"ip xfrm {args}", shell=True, host=host) 28 29 30def check_xfrm_offload_support(): 31 """Skips if iproute2 lacks xfrm offload support.""" 32 out = cmd("ip xfrm state help", fail=False) 33 if "offload" not in out.stdout + out.stderr: 34 raise KsftSkipEx("iproute2 too old, missing xfrm offload") 35 36 37def check_esp_hw_offload(cfg): 38 """Skips if device lacks esp-hw-offload support.""" 39 check_xfrm_offload_support() 40 try: 41 feat = ethtool(f"-k {cfg.ifname}", json=True)[0] 42 except (CmdExitFailure, IndexError) as e: 43 raise KsftSkipEx(f"can't query features: {e}") from e 44 if not feat.get("esp-hw-offload", {}).get("active"): 45 raise KsftSkipEx("Device does not support esp-hw-offload") 46 47 48def get_tx_drops(cfg): 49 """Returns TX dropped counter from the physical device.""" 50 stats = ip("-s -s link show dev " + cfg.ifname, json=True)[0] 51 return stats["stats64"]["tx"]["dropped"] 52 53 54def setup_vxlan_ipsec(cfg, outer_ipver, inner_ipver): 55 """Sets up VXLAN tunnel with IPsec transport-mode crypto-offload.""" 56 vxlan_name = f"vx{os.getpid()}" 57 local_addr = cfg.addr_v[outer_ipver] 58 remote_addr = cfg.remote_addr_v[outer_ipver] 59 60 if inner_ipver == "4": 61 inner_local = f"{INNER_V4_LOCAL}/24" 62 inner_remote = f"{INNER_V4_REMOTE}/24" 63 addr_extra = "" 64 else: 65 inner_local = f"{INNER_V6_LOCAL}/64" 66 inner_remote = f"{INNER_V6_REMOTE}/64" 67 addr_extra = " nodad" 68 69 if outer_ipver == "6": 70 vxlan_opts = "udp6zerocsumtx udp6zerocsumrx" 71 else: 72 vxlan_opts = "noudpcsum" 73 74 # VXLAN tunnel - local side 75 ip(f"link add {vxlan_name} type vxlan id 100 dstport 4789 {vxlan_opts} " 76 f"local {local_addr} remote {remote_addr} dev {cfg.ifname}") 77 defer(ip, f"link del {vxlan_name}") 78 ip(f"addr add {inner_local} dev {vxlan_name}{addr_extra}") 79 ip(f"link set {vxlan_name} up") 80 81 # VXLAN tunnel - remote side 82 ip(f"link add {vxlan_name} type vxlan id 100 dstport 4789 {vxlan_opts} " 83 f"local {remote_addr} remote {local_addr} dev {cfg.remote_ifname}", 84 host=cfg.remote) 85 defer(ip, f"link del {vxlan_name}", host=cfg.remote) 86 ip(f"addr add {inner_remote} dev {vxlan_name}{addr_extra}", 87 host=cfg.remote) 88 ip(f"link set {vxlan_name} up", host=cfg.remote) 89 90 # xfrm state - local outbound SA 91 xfrm(f"state add src {local_addr} dst {remote_addr} " 92 f"proto esp spi {SPI_OUT} " 93 f"{ESP_AEAD} " 94 f"mode transport offload crypto dev {cfg.ifname} dir out") 95 defer(xfrm, f"state del src {local_addr} dst {remote_addr} " 96 f"proto esp spi {SPI_OUT}") 97 98 # xfrm state - local inbound SA 99 xfrm(f"state add src {remote_addr} dst {local_addr} " 100 f"proto esp spi {SPI_IN} " 101 f"{ESP_AEAD} " 102 f"mode transport offload crypto dev {cfg.ifname} dir in") 103 defer(xfrm, f"state del src {remote_addr} dst {local_addr} " 104 f"proto esp spi {SPI_IN}") 105 106 # xfrm state - remote outbound SA (mirror, software crypto) 107 xfrm(f"state add src {remote_addr} dst {local_addr} " 108 f"proto esp spi {SPI_IN} " 109 f"{ESP_AEAD} " 110 f"mode transport", 111 host=cfg.remote) 112 defer(xfrm, f"state del src {remote_addr} dst {local_addr} " 113 f"proto esp spi {SPI_IN}", host=cfg.remote) 114 115 # xfrm state - remote inbound SA (mirror, software crypto) 116 xfrm(f"state add src {local_addr} dst {remote_addr} " 117 f"proto esp spi {SPI_OUT} " 118 f"{ESP_AEAD} " 119 f"mode transport", 120 host=cfg.remote) 121 defer(xfrm, f"state del src {local_addr} dst {remote_addr} " 122 f"proto esp spi {SPI_OUT}", host=cfg.remote) 123 124 # xfrm policy - local out 125 xfrm(f"policy add src {local_addr} dst {remote_addr} " 126 f"proto udp dport 4789 dir out " 127 f"tmpl src {local_addr} dst {remote_addr} proto esp mode transport") 128 defer(xfrm, f"policy del src {local_addr} dst {remote_addr} " 129 f"proto udp dport 4789 dir out") 130 131 # xfrm policy - local in 132 xfrm(f"policy add src {remote_addr} dst {local_addr} " 133 f"proto udp dport 4789 dir in " 134 f"tmpl src {remote_addr} dst {local_addr} proto esp mode transport") 135 defer(xfrm, f"policy del src {remote_addr} dst {local_addr} " 136 f"proto udp dport 4789 dir in") 137 138 # xfrm policy - remote out 139 xfrm(f"policy add src {remote_addr} dst {local_addr} " 140 f"proto udp dport 4789 dir out " 141 f"tmpl src {remote_addr} dst {local_addr} proto esp mode transport", 142 host=cfg.remote) 143 defer(xfrm, f"policy del src {remote_addr} dst {local_addr} " 144 f"proto udp dport 4789 dir out", host=cfg.remote) 145 146 # xfrm policy - remote in 147 xfrm(f"policy add src {local_addr} dst {remote_addr} " 148 f"proto udp dport 4789 dir in " 149 f"tmpl src {local_addr} dst {remote_addr} proto esp mode transport", 150 host=cfg.remote) 151 defer(xfrm, f"policy del src {local_addr} dst {remote_addr} " 152 f"proto udp dport 4789 dir in", host=cfg.remote) 153 154 155def _vxlan_ipsec_variants(): 156 """Generates outer/inner IP version variants.""" 157 for outer in ["4", "6"]: 158 for inner in ["4", "6"]: 159 yield KsftNamedVariant(f"outer_v{outer}_inner_v{inner}", outer, inner) 160 161 162@ksft_variants(_vxlan_ipsec_variants()) 163def test_vxlan_ipsec_crypto_offload(cfg, outer_ipver, inner_ipver): 164 """Tests VXLAN+IPsec crypto-offload has no TX drops.""" 165 cfg.require_ipver(outer_ipver) 166 check_esp_hw_offload(cfg) 167 168 setup_vxlan_ipsec(cfg, outer_ipver, inner_ipver) 169 170 if inner_ipver == "4": 171 inner_local = INNER_V4_LOCAL 172 inner_remote = INNER_V4_REMOTE 173 ping = "ping" 174 else: 175 inner_local = INNER_V6_LOCAL 176 inner_remote = INNER_V6_REMOTE 177 ping = "ping -6" 178 179 cmd(f"{ping} -c 1 -W 2 {inner_remote}") 180 181 drops_before = get_tx_drops(cfg) 182 183 runner = Iperf3Runner(cfg, server_ip=inner_local, 184 client_ip=inner_remote) 185 bw_gbps = runner.measure_bandwidth(reverse=True) 186 187 cfg.wait_hw_stats_settle() 188 drops_after = get_tx_drops(cfg) 189 190 ksft_eq(drops_after - drops_before, 0, 191 comment="TX drops during VXLAN+IPsec") 192 ksft_ge(bw_gbps, 0.1, 193 comment="Minimum 100Mbps over VXLAN+IPsec") 194 195 196def main(): 197 """Runs VXLAN+IPsec crypto-offload GSO selftest.""" 198 with NetDrvEpEnv(__file__, nsim_test=False) as cfg: 199 ksft_run([test_vxlan_ipsec_crypto_offload], args=(cfg,)) 200 ksft_exit() 201 202 203if __name__ == "__main__": 204 main()