From bf817bf94d399fe76549537eec43f4f94244205b Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 31 Jul 2023 21:57:00 +0100 Subject: [PATCH] net adding set_fib call to set FIB route on FreeBSD. --- library/std/src/os/unix/net/datagram.rs | 22 ++++++++++++++++++++++ library/std/src/os/unix/net/stream.rs | 22 ++++++++++++++++++++++ library/std/src/sys/pal/unix/net.rs | 6 ++++++ 3 files changed, 50 insertions(+) diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 34db54235f1c2..cbf30179c25f8 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -890,6 +890,28 @@ impl UnixDatagram { self.0.set_mark(mark) } + /// Set the route FIB table id + /// + /// The kernel allows up to 65536 distinct routes + /// (visible via net.fibs sysctl), this socket option + /// allows to set the id programmatically + #[cfg_attr(target_os = "freebsd", doc = "```no_run")] + #[cfg_attr(not(target_os = "freebsd"), doc = "```ignore")] + /// #![feature(unix_set_fib)] + /// use std::os::unix::net::UnixDatagram; + /// + /// fn main() -> std::io::Result<()> { + /// let sock = UnixDatagram::unbound()?; + /// sock.set_fib(1)?; + /// Ok(()) + /// } + /// ``` + #[cfg(any(doc, target_os = "freebsd"))] + #[unstable(feature = "unix_set_fib", issue = "none")] + pub fn set_fib(&self, fib: i32) -> io::Result<()> { + self.0.set_fib(fib) + } + /// Returns the value of the `SO_ERROR` option. /// /// # Examples diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 41290e0017ac3..9f48bfb562884 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -482,6 +482,28 @@ impl UnixStream { self.0.set_mark(mark) } + /// Set the route FIB table id + /// + /// The kernel allows up to 65536 distinct routes + /// (visible via net.fibs sysctl), this socket option + /// allows to set the id programmatically + #[cfg_attr(target_os = "freebsd", doc = "```no_run")] + #[cfg_attr(not(target_os = "freebsd"), doc = "```ignore")] + /// #![feature(unix_set_fib)] + /// use std::os::unix::net::UnixStream; + /// + /// fn main() -> std::io::Result<()> { + /// let sock = UnixStream::connect("/tmp/sock")?; + /// sock.set_fib(1)?; + /// Ok(()) + /// } + /// ``` + #[cfg(any(doc, target_os = "freebsd",))] + #[unstable(feature = "unix_set_fib", issue = "none")] + pub fn set_fib(&self, fib: i32) -> io::Result<()> { + self.0.set_fib(fib) + } + /// Returns the value of the `SO_ERROR` option. /// /// # Examples diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs index 8f537de7026f5..f82cd1f94b668 100644 --- a/library/std/src/sys/pal/unix/net.rs +++ b/library/std/src/sys/pal/unix/net.rs @@ -504,6 +504,12 @@ impl Socket { setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) } + #[cfg(target_os = "freebsd")] + pub fn set_fib(&self, fib: i32) -> io::Result<()> { + // Allows to bind the socket to special routing rules via ipfw + setsockopt(self, libc::SOL_SOCKET, libc::SO_SETFIB, fib as libc::c_int) + } + pub fn take_error(&self) -> io::Result> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }