Path: blob/master/tools/testing/selftests/drivers/net/hw/ipsec_vxlan.py
216637 views
#!/usr/bin/env python31# SPDX-License-Identifier: GPL-2.02"""Traffic test for VXLAN + IPsec crypto-offload."""34import os56from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_ge7from lib.py import ksft_variants, KsftNamedVariant, KsftSkipEx8from lib.py import CmdExitFailure, NetDrvEpEnv, cmd, defer, ethtool, ip9from lib.py import Iperf3Runner1011# Inner tunnel addresses - TEST-NET-2 (RFC 5737) / doc prefix (RFC 3849)12INNER_V4_LOCAL = "198.51.100.1"13INNER_V4_REMOTE = "198.51.100.2"14INNER_V6_LOCAL = "2001:db8:100::1"15INNER_V6_REMOTE = "2001:db8:100::2"1617# ESP parameters18SPI_OUT = "0x1000"19SPI_IN = "0x1001"20# 128-bit key + 32-bit salt = 20 bytes hex, 128-bit ICV21ESP_AEAD = "aead 'rfc4106(gcm(aes))' 0x" + "01" * 20 + " 128"222324def xfrm(args, host=None):25"""Runs 'ip xfrm' via shell to preserve parentheses in algo names."""26cmd(f"ip xfrm {args}", shell=True, host=host)272829def check_xfrm_offload_support():30"""Skips if iproute2 lacks xfrm offload support."""31out = cmd("ip xfrm state help", fail=False)32if "offload" not in out.stdout + out.stderr:33raise KsftSkipEx("iproute2 too old, missing xfrm offload")343536def check_esp_hw_offload(cfg):37"""Skips if device lacks esp-hw-offload support."""38check_xfrm_offload_support()39try:40feat = ethtool(f"-k {cfg.ifname}", json=True)[0]41except (CmdExitFailure, IndexError) as e:42raise KsftSkipEx(f"can't query features: {e}") from e43if not feat.get("esp-hw-offload", {}).get("active"):44raise KsftSkipEx("Device does not support esp-hw-offload")454647def get_tx_drops(cfg):48"""Returns TX dropped counter from the physical device."""49stats = ip("-s -s link show dev " + cfg.ifname, json=True)[0]50return stats["stats64"]["tx"]["dropped"]515253def setup_vxlan_ipsec(cfg, outer_ipver, inner_ipver):54"""Sets up VXLAN tunnel with IPsec transport-mode crypto-offload."""55vxlan_name = f"vx{os.getpid()}"56local_addr = cfg.addr_v[outer_ipver]57remote_addr = cfg.remote_addr_v[outer_ipver]5859if inner_ipver == "4":60inner_local = f"{INNER_V4_LOCAL}/24"61inner_remote = f"{INNER_V4_REMOTE}/24"62addr_extra = ""63else:64inner_local = f"{INNER_V6_LOCAL}/64"65inner_remote = f"{INNER_V6_REMOTE}/64"66addr_extra = " nodad"6768if outer_ipver == "6":69vxlan_opts = "udp6zerocsumtx udp6zerocsumrx"70else:71vxlan_opts = "noudpcsum"7273# VXLAN tunnel - local side74ip(f"link add {vxlan_name} type vxlan id 100 dstport 4789 {vxlan_opts} "75f"local {local_addr} remote {remote_addr} dev {cfg.ifname}")76defer(ip, f"link del {vxlan_name}")77ip(f"addr add {inner_local} dev {vxlan_name}{addr_extra}")78ip(f"link set {vxlan_name} up")7980# VXLAN tunnel - remote side81ip(f"link add {vxlan_name} type vxlan id 100 dstport 4789 {vxlan_opts} "82f"local {remote_addr} remote {local_addr} dev {cfg.remote_ifname}",83host=cfg.remote)84defer(ip, f"link del {vxlan_name}", host=cfg.remote)85ip(f"addr add {inner_remote} dev {vxlan_name}{addr_extra}",86host=cfg.remote)87ip(f"link set {vxlan_name} up", host=cfg.remote)8889# xfrm state - local outbound SA90xfrm(f"state add src {local_addr} dst {remote_addr} "91f"proto esp spi {SPI_OUT} "92f"{ESP_AEAD} "93f"mode transport offload crypto dev {cfg.ifname} dir out")94defer(xfrm, f"state del src {local_addr} dst {remote_addr} "95f"proto esp spi {SPI_OUT}")9697# xfrm state - local inbound SA98xfrm(f"state add src {remote_addr} dst {local_addr} "99f"proto esp spi {SPI_IN} "100f"{ESP_AEAD} "101f"mode transport offload crypto dev {cfg.ifname} dir in")102defer(xfrm, f"state del src {remote_addr} dst {local_addr} "103f"proto esp spi {SPI_IN}")104105# xfrm state - remote outbound SA (mirror, software crypto)106xfrm(f"state add src {remote_addr} dst {local_addr} "107f"proto esp spi {SPI_IN} "108f"{ESP_AEAD} "109f"mode transport",110host=cfg.remote)111defer(xfrm, f"state del src {remote_addr} dst {local_addr} "112f"proto esp spi {SPI_IN}", host=cfg.remote)113114# xfrm state - remote inbound SA (mirror, software crypto)115xfrm(f"state add src {local_addr} dst {remote_addr} "116f"proto esp spi {SPI_OUT} "117f"{ESP_AEAD} "118f"mode transport",119host=cfg.remote)120defer(xfrm, f"state del src {local_addr} dst {remote_addr} "121f"proto esp spi {SPI_OUT}", host=cfg.remote)122123# xfrm policy - local out124xfrm(f"policy add src {local_addr} dst {remote_addr} "125f"proto udp dport 4789 dir out "126f"tmpl src {local_addr} dst {remote_addr} proto esp mode transport")127defer(xfrm, f"policy del src {local_addr} dst {remote_addr} "128f"proto udp dport 4789 dir out")129130# xfrm policy - local in131xfrm(f"policy add src {remote_addr} dst {local_addr} "132f"proto udp dport 4789 dir in "133f"tmpl src {remote_addr} dst {local_addr} proto esp mode transport")134defer(xfrm, f"policy del src {remote_addr} dst {local_addr} "135f"proto udp dport 4789 dir in")136137# xfrm policy - remote out138xfrm(f"policy add src {remote_addr} dst {local_addr} "139f"proto udp dport 4789 dir out "140f"tmpl src {remote_addr} dst {local_addr} proto esp mode transport",141host=cfg.remote)142defer(xfrm, f"policy del src {remote_addr} dst {local_addr} "143f"proto udp dport 4789 dir out", host=cfg.remote)144145# xfrm policy - remote in146xfrm(f"policy add src {local_addr} dst {remote_addr} "147f"proto udp dport 4789 dir in "148f"tmpl src {local_addr} dst {remote_addr} proto esp mode transport",149host=cfg.remote)150defer(xfrm, f"policy del src {local_addr} dst {remote_addr} "151f"proto udp dport 4789 dir in", host=cfg.remote)152153154def _vxlan_ipsec_variants():155"""Generates outer/inner IP version variants."""156for outer in ["4", "6"]:157for inner in ["4", "6"]:158yield KsftNamedVariant(f"outer_v{outer}_inner_v{inner}", outer, inner)159160161@ksft_variants(_vxlan_ipsec_variants())162def test_vxlan_ipsec_crypto_offload(cfg, outer_ipver, inner_ipver):163"""Tests VXLAN+IPsec crypto-offload has no TX drops."""164cfg.require_ipver(outer_ipver)165check_esp_hw_offload(cfg)166167setup_vxlan_ipsec(cfg, outer_ipver, inner_ipver)168169if inner_ipver == "4":170inner_local = INNER_V4_LOCAL171inner_remote = INNER_V4_REMOTE172ping = "ping"173else:174inner_local = INNER_V6_LOCAL175inner_remote = INNER_V6_REMOTE176ping = "ping -6"177178cmd(f"{ping} -c 1 -W 2 {inner_remote}")179180drops_before = get_tx_drops(cfg)181182runner = Iperf3Runner(cfg, server_ip=inner_local,183client_ip=inner_remote)184bw_gbps = runner.measure_bandwidth(reverse=True)185186cfg.wait_hw_stats_settle()187drops_after = get_tx_drops(cfg)188189ksft_eq(drops_after - drops_before, 0,190comment="TX drops during VXLAN+IPsec")191ksft_ge(bw_gbps, 0.1,192comment="Minimum 100Mbps over VXLAN+IPsec")193194195def main():196"""Runs VXLAN+IPsec crypto-offload GSO selftest."""197with NetDrvEpEnv(__file__, nsim_test=False) as cfg:198ksft_run([test_vxlan_ipsec_crypto_offload], args=(cfg,))199ksft_exit()200201202if __name__ == "__main__":203main()204205206