Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163438737
D58281.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D58281.id.diff
View Options
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -925,7 +925,7 @@
* to any endpoint address, local or not.
*/
if ((inp->inp_flags & INP_BINDANY) == 0 &&
- ifa_ifwithaddr_check((const struct sockaddr *)&sin) == 0)
+ ifa_ifwithaddr_fib_check((const struct sockaddr *)&sin, fib) == 0)
return (EADDRNOTAVAIL);
}
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -860,7 +860,7 @@
{
struct sockaddr_in *addr = (struct sockaddr_in *)nam;
struct inpcb *inp;
- int error;
+ int fib, error;
if (nam->sa_family != AF_INET)
return (EAFNOSUPPORT);
@@ -874,11 +874,14 @@
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip_bind: inp == NULL"));
+ fib = V_rip_bind_all_fibs == 0 ? inp->inp_inc.inc_fibnum :
+ RT_ALL_FIBS;
+
if (CK_STAILQ_EMPTY(&V_ifnet) ||
(addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) ||
(addr->sin_addr.s_addr &&
(inp->inp_flags & INP_BINDANY) == 0 &&
- ifa_ifwithaddr_check((struct sockaddr *)addr) == 0))
+ ifa_ifwithaddr_fib_check((struct sockaddr *)addr, fib) == 0))
return (EADDRNOTAVAIL);
INP_WLOCK(inp);
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -208,7 +208,7 @@
sin6.sin6_addr = *laddr;
NET_EPOCH_ENTER(et);
- if ((ifa = ifa_ifwithaddr((const struct sockaddr *)&sin6)) ==
+ if ((ifa = ifa_ifwithaddr_fib((const struct sockaddr *)&sin6, fib)) ==
NULL && (inp->inp_flags & INP_BINDANY) == 0) {
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -743,7 +743,7 @@
struct inpcb *inp;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
struct ifaddr *ifa = NULL;
- int error = 0;
+ int fib, error = 0;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip6_bind: inp == NULL"));
@@ -759,9 +759,12 @@
if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0)
return (error);
+ fib = V_rip_bind_all_fibs == 0 ? inp->inp_inc.inc_fibnum :
+ RT_ALL_FIBS;
+
NET_EPOCH_ENTER(et);
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) &&
- (ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) {
+ (ifa = ifa_ifwithaddr_fib((struct sockaddr *)addr, fib)) == NULL) {
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
diff --git a/tests/sys/netinet/Makefile b/tests/sys/netinet/Makefile
--- a/tests/sys/netinet/Makefile
+++ b/tests/sys/netinet/Makefile
@@ -30,6 +30,7 @@
redirect
ATF_TESTS_PYTEST+= carp.py \
+ fib_bind.py \
igmp.py \
ip_mroute.py \
tcp_hpts_test.py
diff --git a/tests/sys/netinet/fib_bind.py b/tests/sys/netinet/fib_bind.py
new file mode 100644
--- /dev/null
+++ b/tests/sys/netinet/fib_bind.py
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2026 Stormshield
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+import pytest
+import errno
+import os
+import socket
+import struct
+import sys
+import logging
+
+from atf_python.sys.net.vnet import VnetTestTemplate
+from atf_python.sys.net.tools import ToolsHelper
+
+def _common(tunable, addr, domain, type, proto):
+ """
+ Test what happens when we try to bind a socket to an
+ address that is not present in the current FIB.
+ """
+ sysctl_output = ToolsHelper.get_output(f"sysctl {tunable}")
+ tunable_val = int(sysctl_output.split(":")[1])
+ if tunable_val != 0:
+ pytest.skip(f"{tunable} must be set to 0")
+
+ port = 12345 if type != socket.SOCK_RAW else 0
+ s = socket.socket(domain, type, proto)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_SETFIB, 0)
+
+ failed = False
+ try:
+ s.bind((addr, port))
+ except OSError as e:
+ assert e.errno == errno.EADDRNOTAVAIL
+ failed = True
+ assert failed
+
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_SETFIB, 1)
+
+ failed = False
+ try:
+ s.bind((addr, port))
+ except OSError:
+ failed = True
+ assert not failed
+ s.close()
+
+class TestFibBind(VnetTestTemplate):
+ REQUIRED_MODULES = []
+ TOPOLOGY = {
+ "vnet1": { "ifaces": [ "if1", "if2" ] },
+ "if1": {
+ "prefixes4": [("192.168.1.1/24", "192.168.1.2/24")],
+ "fib": (0, 0),
+ },
+ "if2": {
+ "prefixes4": [("192.168.2.1/24", "192.168.2.2/24")],
+ "fib": (1, 0),
+ },
+ }
+
+ def setup_method(self, method):
+ super().setup_method(method)
+
+ def test_TCP(self):
+ _common("net.inet.tcp.bind_all_fibs", "192.168.2.1", socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
+
+ def test_UDP(self):
+ _common("net.inet.udp.bind_all_fibs", "192.168.2.1", socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
+
+ def test_RAW(self):
+ _common("net.inet.raw.bind_all_fibs", "192.168.2.1", socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
+
+class TestFibBind6(VnetTestTemplate):
+ REQUIRED_MODULES = []
+ TOPOLOGY = {
+ "vnet1": { "ifaces": [ "if1", "if2" ] },
+ "if1": {
+ "prefixes6": [("2001:db8:0:1::1/64", "2001:db8:0:1::2/64")],
+ "fib": (0, 0),
+ },
+ "if2": {
+ "prefixes6": [("2001:db8:0:2::1/64", "2001:db8:0:2::2/64")],
+ "fib": (1, 0),
+ },
+ }
+
+ def setup_method(self, method):
+ super().setup_method(method)
+
+ def test_TCP(self):
+ _common("net.inet.tcp.bind_all_fibs", "2001:db8:0:2::1", socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP)
+
+ def test_UDP(self):
+ _common("net.inet.udp.bind_all_fibs", "2001:db8:0:2::1", socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
+
+ def test_RAW(self):
+ _common("net.inet.raw.bind_all_fibs", "2001:db8:0:2::1", socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_IPV6)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 24, 5:13 AM (2 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35431881
Default Alt Text
D58281.id.diff (5 KB)
Attached To
Mode
D58281: bind(2): Lookup local address in current FIB if '*.bind_all_fibs' is active
Attached
Detach File
Event Timeline
Log In to Comment