1# 2# Copyright (c) 2026 Stormshield 3# 4# SPDX-License-Identifier: BSD-2-Clause 5# 6 7import pytest 8import errno 9import os 10import socket 11import struct 12import sys 13import logging 14 15from atf_python.sys.net.vnet import VnetTestTemplate 16from atf_python.sys.net.tools import ToolsHelper 17 18def _common(tunable, addr, domain, type, proto): 19 """ 20 Test what happens when we try to bind a socket to an 21 address that is not present in the current FIB. 22 """ 23 sysctl_output = ToolsHelper.get_output(f"sysctl {tunable}") 24 tunable_val = int(sysctl_output.split(":")[1]) 25 if tunable_val != 0: 26 pytest.skip(f"{tunable} must be set to 0") 27 28 port = 12345 if type != socket.SOCK_RAW else 0 29 s = socket.socket(domain, type, proto) 30 s.setsockopt(socket.SOL_SOCKET, socket.SO_SETFIB, 0) 31 32 failed = False 33 try: 34 s.bind((addr, port)) 35 except OSError as e: 36 assert e.errno == errno.EADDRNOTAVAIL 37 failed = True 38 assert failed 39 40 s.setsockopt(socket.SOL_SOCKET, socket.SO_SETFIB, 1) 41 42 failed = False 43 try: 44 s.bind((addr, port)) 45 except OSError: 46 failed = True 47 assert not failed 48 s.close() 49 50class TestFibBind(VnetTestTemplate): 51 REQUIRED_MODULES = [] 52 TOPOLOGY = { 53 "vnet1": { "ifaces": [ "if1", "if2" ] }, 54 "if1": { 55 "prefixes4": [("192.168.1.1/24", "192.168.1.2/24")], 56 "fib": (0, 0), 57 }, 58 "if2": { 59 "prefixes4": [("192.168.2.1/24", "192.168.2.2/24")], 60 "fib": (1, 0), 61 }, 62 } 63 64 def setup_method(self, method): 65 super().setup_method(method) 66 67 def test_TCP(self): 68 _common("net.inet.tcp.bind_all_fibs", "192.168.2.1", socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) 69 70 def test_UDP(self): 71 _common("net.inet.udp.bind_all_fibs", "192.168.2.1", socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 72 73 def test_RAW(self): 74 _common("net.inet.raw.bind_all_fibs", "192.168.2.1", socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) 75 76class TestFibBind6(VnetTestTemplate): 77 REQUIRED_MODULES = [] 78 TOPOLOGY = { 79 "vnet1": { "ifaces": [ "if1", "if2" ] }, 80 "if1": { 81 "prefixes6": [("2001:db8:0:1::1/64", "2001:db8:0:1::2/64")], 82 "fib": (0, 0), 83 }, 84 "if2": { 85 "prefixes6": [("2001:db8:0:2::1/64", "2001:db8:0:2::2/64")], 86 "fib": (1, 0), 87 }, 88 } 89 90 def setup_method(self, method): 91 super().setup_method(method) 92 93 def test_TCP(self): 94 _common("net.inet.tcp.bind_all_fibs", "2001:db8:0:2::1", socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP) 95 96 def test_UDP(self): 97 _common("net.inet.udp.bind_all_fibs", "2001:db8:0:2::1", socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 98 99 def test_RAW(self): 100 _common("net.inet.raw.bind_all_fibs", "2001:db8:0:2::1", socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_IPV6) 101