aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2025-02-06 14:16:21 +0000
committerMark Johnston <markj@FreeBSD.org>2025-02-06 14:16:21 +0000
commitcaccbaef8e263b1d769e7bcac1c4617bdc12d484 (patch)
treebda6334a8beaaea3ca892f146243505434c22c52 /sys/kern
parent7034563f8ef3acbe5bada582f0bb335fcba9dfb4 (diff)
socket: Move SO_SETFIB handling to protocol layers
In particular, we store a FIB number in both struct socket and in struct inpcb. When updating the FIB number with setsockopt(SO_SETFIB), make the update atomic. This is required to support the new bind_all_fibs mode, since in that mode changing the FIB of a bound socket is not permitted. This requires a bit more code, but avoids a layering violation in sosetopt(), where we hard-code the list of protocol families that implement SO_SETFIB. Reviewed by: glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D48666
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_socket.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index c4ebb43eef18..65cea2e067cf 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -3699,6 +3699,19 @@ sorflush(struct socket *so)
}
+int
+sosetfib(struct socket *so, int fibnum)
+{
+ if (fibnum < 0 || fibnum >= rt_numfibs)
+ return (EINVAL);
+
+ SOCK_LOCK(so);
+ so->so_fibnum = fibnum;
+ SOCK_UNLOCK(so);
+
+ return (0);
+}
+
#ifdef SOCKET_HHOOK
/*
* Wrapper for Socket established helper hook.
@@ -3847,21 +3860,7 @@ sosetopt(struct socket *so, struct sockopt *sopt)
break;
case SO_SETFIB:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- goto bad;
-
- if (optval < 0 || optval >= rt_numfibs) {
- error = EINVAL;
- goto bad;
- }
- if (((so->so_proto->pr_domain->dom_family == PF_INET) ||
- (so->so_proto->pr_domain->dom_family == PF_INET6) ||
- (so->so_proto->pr_domain->dom_family == PF_ROUTE)))
- so->so_fibnum = optval;
- else
- so->so_fibnum = 0;
+ error = so->so_proto->pr_ctloutput(so, sopt);
break;
case SO_USER_COOKIE: