Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions lisa/microsoft/testsuites/network/xfrm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
from __future__ import annotations

from assertpy import assert_that

from lisa import (
Node,
SkippedException,
TestCaseMetadata,
TestSuite,
TestSuiteMetadata,
simple_requirement,
)
from lisa.operating_system import BSD, Windows
from lisa.sut_orchestrator import AZURE, HYPERV, READY
from lisa.tools import KernelConfig, Lsmod, Modprobe


@TestSuiteMetadata(
area="network",
category="functional",
description="""
This test suite validates XFRM (IPsec) interface functionality.
XFRM interfaces are used for IPsec VPN tunnels and are essential
for secure network communications.
""",
requirement=simple_requirement(
supported_platform_type=[AZURE, READY, HYPERV],
unsupported_os=[BSD, Windows],
),
)
class XfrmSuite(TestSuite):
@TestCaseMetadata(
description="""
This test case verifies that the xfrm_interface kernel module
can be loaded and provides the expected functionality.

Steps:
1. Check if CONFIG_XFRM_INTERFACE is enabled in kernel config.
2. Load the xfrm_interface module if not already loaded.
3. Verify the module is loaded successfully.
4. Create a test xfrm interface (xfrm0).
5. Verify the interface was created.
6. Clean up the test interface.

""",
priority=2,
)
def verify_xfrm_interface(self, node: Node) -> None:
kernel_config = node.tools[KernelConfig]

# Check kernel configuration
if not kernel_config.is_enabled("CONFIG_XFRM_INTERFACE"):
raise SkippedException("CONFIG_XFRM_INTERFACE is not enabled in kernel")

# Check if xfrm_interface is built-in or needs to be loaded as module
is_builtin = kernel_config.is_built_in("CONFIG_XFRM_INTERFACE")

modprobe = node.tools[Modprobe]
lsmod = node.tools[Lsmod]

if not is_builtin:
# Load the module if not already loaded
if not lsmod.module_exists("xfrm_interface", force_run=True):
modprobe.load("xfrm_interface")

# Verify module is loaded
module_loaded = lsmod.module_exists("xfrm_interface", force_run=True)
assert_that(module_loaded).described_as(
"xfrm_interface module should be loaded"
).is_true()

# Create a test xfrm interface
# xfrm interfaces require an interface ID (if_id) parameter
interface_name = "xfrm0"
if_id = "100"

try:
# Create xfrm interface
# ip link add <name> type xfrm dev <physical_dev> if_id <id>
# We need to find an existing physical interface first
default_nic = node.nics.default_nic
cmd = (
f"ip link add {interface_name} type xfrm "
f"dev {default_nic} if_id {if_id}"
)
result = node.execute(cmd, sudo=True)

# Check if interface creation succeeded
if result.exit_code == 0:
# Verify interface exists
show_cmd = f"ip link show {interface_name}"
result = node.execute(show_cmd, sudo=True)
assert_that(result.exit_code).described_as(
f"xfrm interface {interface_name} should exist"
).is_equal_to(0)
assert_that(result.stdout).described_as(
f"output should contain {interface_name}"
).contains(interface_name)
else:
# Interface creation failed - this indicates XFRM support issue
raise AssertionError(
f"Failed to create xfrm interface. "
f"Exit code: {result.exit_code}, "
f"stderr: {result.stderr}"
)

finally:
# Clean up - delete the test interface if it was created
node.execute(f"ip link del {interface_name}", sudo=True)

@TestCaseMetadata(
description="""
This test case verifies that the xfrm_interface kernel module
can be loaded and unloaded without issues.

Steps:
1. Check if CONFIG_XFRM_INTERFACE is enabled and not built-in.
2. Unload the xfrm_interface module if loaded.
3. Load the xfrm_interface module.
4. Verify the module is loaded.
5. Unload the module.
6. Verify the module is unloaded.

""",
priority=3,
)
def verify_xfrm_interface_load_unload(self, node: Node) -> None:
kernel_config = node.tools[KernelConfig]
modprobe = node.tools[Modprobe]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

lsmod = node.tools[Lsmod]

# Check kernel configuration
if not kernel_config.is_enabled("CONFIG_XFRM_INTERFACE"):
raise SkippedException("CONFIG_XFRM_INTERFACE is not enabled in kernel")

# Skip if built-in (can't unload built-in modules)
if kernel_config.is_built_in("CONFIG_XFRM_INTERFACE"):
raise SkippedException(
"CONFIG_XFRM_INTERFACE is built-in, " "cannot test module load/unload"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"CONFIG_XFRM_INTERFACE is built-in, cannot test module load/unload"

)

# Ensure module is unloaded first
if lsmod.module_exists("xfrm_interface", force_run=True):
modprobe.remove(["xfrm_interface"])

# Verify module is unloaded
module_exists = lsmod.module_exists("xfrm_interface", force_run=True)
assert_that(module_exists).described_as(
"xfrm_interface module should be unloaded before test"
).is_false()

# Load the module
modprobe.load("xfrm_interface")

# Verify module is loaded
module_exists = lsmod.module_exists("xfrm_interface", force_run=True)
assert_that(module_exists).described_as(
"xfrm_interface module should be loaded after modprobe"
).is_true()

# Unload the module
modprobe.remove(["xfrm_interface"])

# Verify module is unloaded
module_exists = lsmod.module_exists("xfrm_interface", force_run=True)
assert_that(module_exists).described_as(
"xfrm_interface module should be unloaded after removal"
).is_false()

# Reload the module to leave system in working state
modprobe.load("xfrm_interface")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep the original state, and decide to unload or load it to restore it into original state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Also updated in the verify_xfrm_interface function

Loading