diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2025-02-06 14:16:21 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2025-02-06 14:16:21 +0000 |
| commit | caccbaef8e263b1d769e7bcac1c4617bdc12d484 (patch) | |
| tree | bda6334a8beaaea3ca892f146243505434c22c52 /sys/kern | |
| parent | 7034563f8ef3acbe5bada582f0bb335fcba9dfb4 (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.c | 29 |
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: |
