Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to bind socket to FIB on a FreeBSD #271

Merged
merged 4 commits into from Nov 1, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/sys/unix.rs
Expand Up @@ -1348,6 +1348,31 @@ impl crate::Socket {
.map(|_| ())
}

/// Sets the value for the `SO_SETFIB` option on this socket.
wladwm marked this conversation as resolved.
Show resolved Hide resolved
///
/// Bind socket to the specified forwarding table (VRF) on a *BSD OS
wladwm marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(all(
feature = "all",
any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")
wladwm marked this conversation as resolved.
Show resolved Hide resolved
))]
#[cfg_attr(
docsrs,
doc(cfg(all(
feature = "all",
any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")
)))
)]
pub fn set_fib(&self, fib: u32) -> io::Result<()> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setfib - it's another syscall, that set FIB for current process, so all sockets will have specified fib by default.
setsockopt set fib only for exact socket.
In freebsd sources SO_SETFIB using with int.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setfib - it's another syscall, that set FIB for current process, so all sockets will have specified fib by default. setsockopt set fib only for exact socket.

Right, but it's the same option right? That system call just does it process wide.

In freebsd sources SO_SETFIB using with int.

But in C 80% of the input is an int, which b.t.w only has to be 16 bits. However we should try to provide a type that matches the expected input better. For example you're already using an unsigned integer, not a signed one.

P.S. please don't resolve conversations that aren't resolved.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've check with the FreeBSD discord and they recommend u32 as well so going with that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we will take a look on freebsd sources:
user side
https://github.com/freebsd/freebsd-src/blob/main/sbin/route/route.c
it uses exactly int
at kernel side (https://github.com/freebsd/freebsd-src/blob/main/sys/sys/socketvar.h) field so_fibnum also has type int.
FreeBSD has only up to 16 FIBs and FIB should not be negative. So I think it for possible future extensions.

syscall!(setsockopt(
self.as_raw(),
libc::SOL_SOCKET,
libc::SO_SETFIB,
(&fib as *const u32).cast(),
mem::size_of::<u32>() as libc::socklen_t,
))
.map(|_| ())
}

/// Sets the value for `IP_BOUND_IF` option on this socket.
///
/// If a socket is bound to an interface, only packets received from that
Expand Down