Skip to content

Commit 10ebf45

Browse files
committed
Add SO_BINDTODEVICE sockopt
This is available only on Linux as far I know, [socket(7)](https://linux.die.net/man/7/socket) has some information about the `SO_BINDTODEVICE` sockopt. In simple words it binds a socket to an specific network device (specified as an string like "wlo1", "eth0", etc.), to only process packets from that device. Signed-off-by: Jean Pierre Dudey <[email protected]>
1 parent a937988 commit 10ebf45

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2727
(#[1208](https://github.com/nix-rust/nix/pull/1208))
2828
- Added support for `SCM_CREDS` messages (`UnixCredentials`) on FreeBSD/DragonFly
2929
(#[1216](https://github.com/nix-rust/nix/pull/1216))
30+
- Added `BindToDevice` socket option (sockopt) on Linux
31+
(#[1233](https://github.com/nix-rust/nix/pull/1233))
3032

3133
### Changed
3234
- Changed `fallocate` return type from `c_int` to `()` (#[1201](https://github.com/nix-rust/nix/pull/1201))

src/sys/socket/sockopt.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ sockopt_impl!(SetOnly, RcvBufForce, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usiz
259259
sockopt_impl!(SetOnly, SndBufForce, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize);
260260
sockopt_impl!(GetOnly, SockType, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType);
261261
sockopt_impl!(GetOnly, AcceptConn, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool);
262+
#[cfg(target_os = "linux")]
263+
sockopt_impl!(Both, BindToDevice, libc::SOL_SOCKET, libc::SO_BINDTODEVICE, OsString<[u8; libc::IFNAMSIZ]>);
262264
#[cfg(any(target_os = "android", target_os = "linux"))]
263265
sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in);
264266
sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);

test/sys/test_sockopt.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,26 @@ fn test_tcp_congestion() {
5151
val
5252
);
5353
}
54+
55+
#[test]
56+
#[cfg(target_os = "linux")]
57+
fn test_bindtodevice() {
58+
use nix::Error;
59+
use nix::errno::Errno;
60+
61+
let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
62+
63+
let val = getsockopt(fd, sockopt::BindToDevice).unwrap();
64+
match setsockopt(fd, sockopt::BindToDevice, &val) {
65+
// SO_BINDTODEVICE requires root, ignore the error as this could break
66+
// the CI.
67+
Err(Error::Sys(Errno::EPERM)) => (),
68+
Err(e) => panic!("{}", e),
69+
Ok(()) => (),
70+
}
71+
72+
assert_eq!(
73+
getsockopt(fd, sockopt::BindToDevice).unwrap(),
74+
val
75+
);
76+
}

0 commit comments

Comments
 (0)