tun2proxy / rust-tun

TUN device creation and handling.
https://docs.rs/tun2/
30 stars 13 forks source link

Add support of freebsd #3

Closed SajjadPourali closed 3 months ago

SajjadPourali commented 5 months ago

Based on the patch provided by @yurivict for 'tun', it appears that FreeBSD and Linux APIs are the same. We just need to add FreeBSD to the target lists in the platform module. For more information, refer to this link

ssrlive commented 5 months ago

you mean, just simplely add a tag target_os = "freebsd" , tun2 will support freebsd fine? like this

#[cfg(target_os = "linux", target_os = "freebsd")]
pub mod linux;
#[cfg(target_os = "linux", target_os = "freebsd")]
pub use self::linux::{create, Configuration, Device, Queue};
SajjadPourali commented 5 months ago

it appears that the provided patch is not sufficient. Let's keep it open for the future improvement.

root@free:~/rust-tun # uname -a
FreeBSD free 14.0-RELEASE FreeBSD 14.0-RELEASE #0 releng/14.0-n265380-f9716eee8ab4: Fri Nov 10 05:54:07 UTC 2023     root@releng1.nyi.freebsd.org:/usr/obj/usr/src/arm64.aarch64/sys/GENERIC arm64
root@free:~/rust-tun # cargo check
    Checking tun2 v0.6.2 (/root/rust-tun)
error[E0433]: failed to resolve: could not find `linux` in `platform`
  --> src/platform/freebsd/device.rs:34:15
   |
34 |     platform::linux::sys::*,
   |               ^^^^^ could not find `linux` in `platform`

error[E0432]: unresolved imports `libc::IFF_MULTI_QUEUE`, `libc::IFF_NO_PI`, `libc::IFF_TAP`, `libc::IFF_TUN`
  --> src/platform/freebsd/device.rs:16:44
   |
16 |     self, c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_RUNNING, IFF_TAP,
   |                                            ^^^^^^^^^^^^^^^  ^^^^^^^^^               ^^^^^^^ no `IFF_TAP` in the root
   |                                            |                |
   |                                            |                no `IFF_NO_PI` in the root
   |                                            no `IFF_MULTI_QUEUE` in the root
17 |     IFF_TUN, IFF_UP, IFNAMSIZ, O_RDWR, SOCK_DGRAM,
   |     ^^^^^^^ no `IFF_TUN` in the root
   |
help: a similar name exists in the module
   |
16 |     self, c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NOARP, IFF_RUNNING, IFF_TAP,
   |                                                             ~~~~~~~~~
help: a similar name exists in the module
   |
16 |     self, c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_RUNNING, IFF_UP,
   |                                                                                     ~~~~~~
help: a similar name exists in the module
   |
17 |     IFF_UP, IFF_UP, IFNAMSIZ, O_RDWR, SOCK_DGRAM,
   |     ~~~~~~

error[E0432]: unresolved import `ioctl`
  --> src/platform/freebsd/sys.rs:17:5
   |
17 | use ioctl::*;
   |     ^^^^^ use of undeclared crate or module `ioctl`

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:20:1
   |
20 | ioctl!(bad read siocgifflags with 0x8913; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:21:1
   |
21 | ioctl!(bad write siocsifflags with 0x8914; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:22:1
   |
22 | ioctl!(bad read siocgifaddr with 0x8915; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:23:1
   |
23 | ioctl!(bad write siocsifaddr with 0x8916; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:24:1
   |
24 | ioctl!(bad read siocgifdstaddr with 0x8917; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:25:1
   |
25 | ioctl!(bad write siocsifdstaddr with 0x8918; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:26:1
   |
26 | ioctl!(bad read siocgifbrdaddr with 0x8919; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:27:1
   |
27 | ioctl!(bad write siocsifbrdaddr with 0x891a; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:28:1
   |
28 | ioctl!(bad read siocgifnetmask with 0x891b; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:29:1
   |
29 | ioctl!(bad write siocsifnetmask with 0x891c; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:30:1
   |
30 | ioctl!(bad read siocgifmtu with 0x8921; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:31:1
   |
31 | ioctl!(bad write siocsifmtu with 0x8922; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:32:1
   |
32 | ioctl!(bad write siocsifname with 0x8923; ifreq);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:34:1
   |
34 | ioctl!(write tunsetiff with b'T', 202; c_int);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:35:1
   |
35 | ioctl!(write tunsetpersist with b'T', 203; c_int);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:36:1
   |
36 | ioctl!(write tunsetowner with b'T', 204; c_int);
   | ^^^^^

error: cannot find macro `ioctl` in this scope
  --> src/platform/freebsd/sys.rs:37:1
   |
37 | ioctl!(write tunsetgroup with b'T', 206; c_int);
   | ^^^^^

warning: unused imports: `c_int`, `ifreq`
  --> src/platform/freebsd/sys.rs:18:12
   |
18 | use libc::{c_int, ifreq};
   |            ^^^^^  ^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

error[E0308]: mismatched types
  --> src/platform/freebsd/device.rs:85:39
   |
85 |               req.ifr_ifru.ifru_flags = device_type
   |  _____________-----------------------___^
   | |             |
   | |             expected due to the type of this binding
86 | |                 | if packet_information { 0 } else { iff_no_pi }
87 | |                 | if queues_num > 1 { iff_multi_queue } else { 0 };
   | |__________________________________________________________________^ expected `[i16; 2]`, found `i16`

error[E0425]: cannot find function `tunsetiff` in this scope
  --> src/platform/freebsd/device.rs:93:20
   |
93 |                 if tunsetiff(tun.0, &mut req as *mut _ as *mut _) < 0 {
   |                    ^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `tunsetpersist` in this scope
   --> src/platform/freebsd/device.rs:133:16
    |
133 |             if tunsetpersist(self.as_raw_fd(), &1) < 0 {
    |                ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `tunsetowner` in this scope
   --> src/platform/freebsd/device.rs:144:16
    |
144 |             if tunsetowner(self.as_raw_fd(), &value) < 0 {
    |                ^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `tunsetgroup` in this scope
   --> src/platform/freebsd/device.rs:155:16
    |
155 |             if tunsetgroup(self.as_raw_fd(), &value) < 0 {
    |                ^^^^^^^^^^^ not found in this scope

error[E0609]: no field `ifru_newname` on type `__c_anonymous_ifr_ifru`
   --> src/platform/freebsd/device.rs:222:30
    |
222 |                 req.ifr_ifru.ifru_newname.as_mut_ptr(),
    |                              ^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `ifru_addr`, `ifru_dstaddr`, `ifru_broadaddr`, `ifru_buffer`, `ifru_flags` ... and 10 others

error[E0425]: cannot find function `siocsifname` in this scope
   --> src/platform/freebsd/device.rs:226:16
    |
226 |             if siocsifname(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocgifflags` in this scope
   --> src/platform/freebsd/device.rs:240:16
    |
240 |             if siocgifflags(self.ctl.as_raw_fd(), &mut req) < 0 {
    |                ^^^^^^^^^^^^ not found in this scope

error[E0368]: binary assignment operation `|=` cannot be applied to type `[i16; 2]`
   --> src/platform/freebsd/device.rs:245:17
    |
245 |                 req.ifr_ifru.ifru_flags |= (IFF_UP | IFF_RUNNING) as c_short;
    |                 -----------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                 |
    |                 cannot use `|=` on type `[i16; 2]`

error[E0368]: binary assignment operation `&=` cannot be applied to type `[i16; 2]`
   --> src/platform/freebsd/device.rs:247:17
    |
247 |                 req.ifr_ifru.ifru_flags &= !(IFF_UP as c_short);
    |                 -----------------------^^^^^^^^^^^^^^^^^^^^^^^^
    |                 |
    |                 cannot use `&=` on type `[i16; 2]`

error[E0425]: cannot find function `siocsifflags` in this scope
   --> src/platform/freebsd/device.rs:250:16
    |
250 |             if siocsifflags(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocgifaddr` in this scope
   --> src/platform/freebsd/device.rs:262:16
    |
262 |             if siocgifaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
    |                ^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocsifaddr` in this scope
   --> src/platform/freebsd/device.rs:275:16
    |
275 |             if siocsifaddr(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocgifdstaddr` in this scope
   --> src/platform/freebsd/device.rs:287:16
    |
287 |             if siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
    |                ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocsifdstaddr` in this scope
   --> src/platform/freebsd/device.rs:300:16
    |
300 |             if siocsifdstaddr(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocgifbrdaddr` in this scope
   --> src/platform/freebsd/device.rs:312:16
    |
312 |             if siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) < 0 {
    |                ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocsifbrdaddr` in this scope
   --> src/platform/freebsd/device.rs:325:16
    |
325 |             if siocsifbrdaddr(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocgifnetmask` in this scope
   --> src/platform/freebsd/device.rs:337:16
    |
337 |             if siocgifnetmask(self.ctl.as_raw_fd(), &mut req) < 0 {
    |                ^^^^^^^^^^^^^^ not found in this scope

error[E0609]: no field `ifru_netmask` on type `__c_anonymous_ifr_ifru`
   --> src/platform/freebsd/device.rs:341:41
    |
341 |             SockAddr::new(&req.ifr_ifru.ifru_netmask).map(Into::into)
    |                                         ^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `ifru_addr`, `ifru_dstaddr`, `ifru_broadaddr`, `ifru_buffer`, `ifru_flags` ... and 10 others

error[E0609]: no field `ifru_netmask` on type `__c_anonymous_ifr_ifru`
   --> src/platform/freebsd/device.rs:348:26
    |
348 |             req.ifr_ifru.ifru_netmask = SockAddr::from(value).into();
    |                          ^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `ifru_addr`, `ifru_dstaddr`, `ifru_broadaddr`, `ifru_buffer`, `ifru_flags` ... and 10 others

error[E0425]: cannot find function `siocsifnetmask` in this scope
   --> src/platform/freebsd/device.rs:350:16
    |
350 |             if siocsifnetmask(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocgifmtu` in this scope
   --> src/platform/freebsd/device.rs:362:16
    |
362 |             if siocgifmtu(self.ctl.as_raw_fd(), &mut req) < 0 {
    |                ^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `siocsifmtu` in this scope
   --> src/platform/freebsd/device.rs:375:16
    |
375 |             if siocsifmtu(self.ctl.as_raw_fd(), &req) < 0 {
    |                ^^^^^^^^^^ not found in this scope

Some errors have detailed explanations: E0308, E0368, E0425, E0432, E0433, E0609.
For more information about an error, try `rustc --explain E0308`.
warning: `tun2` (lib) generated 1 warning
error: could not compile `tun2` (lib) due to 43 previous errors; 1 warning emitted
root@free:~/rust-tun #
yurivict commented 5 months ago

This patch is sufficient to build narrowlink. But maybe it isn't sufficient in general.

M0dEx commented 5 months ago

I think there are multiple minor changes that are required to get this working:

  1. platform/mod.rs:
    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
    pub mod linux;
    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
    pub use self::linux::{create, Configuration, Device, Queue};
  2. Cargo.toml
    [target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos", target_os = "android"))'.dependencies]
    ioctl = { version = "0.8", package = "ioctl-sys" }

In the initial comment by @ssrlive, the any specifier was missing in the platform/mod.rs file. Many of the errors were also due to missing ioctl, which should be fixed by the second change I proposed.

Could you try this again with the suggested changes? I do not have a FreeBSD VM available to me at the moment.

ssrlive commented 5 months ago

ioctl-sys support openbsb and not support freebsd.

xmh0511 commented 4 months ago

Since we have replaced ioctl-sys with nix, nix supports freebsd, this platform can be achieved after doing minor changes, I think. People having FreeBSD, OpenBSD environments can have a try to test whether the change works

  1. platform/mod.rs:
    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
    pub mod linux;
    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
    pub use self::linux::{create, Device, PlatformConfig};
  2. Cargo.toml
    [target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos", target_os = "android"))'.dependencies]
    nix = { version = "0.27", features = ["ioctl"] }

    If it works, I think changing the name of the module linux to unix_like to cover these platforms is reasonable.

ssrlive commented 4 months ago

emm. sounds good.

SajjadPourali commented 4 months ago

@xmh0511: FreeBSD uses slightly different APIs. I believe https://github.com/LaKabane/libtuntap/blob/master/tuntap-unix-freebsd.c could be inspiring for implementation.

root@freebsd:/home/test/rust-tun # git diff
diff --git a/Cargo.toml b/Cargo.toml
index be374c1..79eb3c8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@ tokio = { version = "1", features = [
 ], optional = true }
 tokio-util = { version = "0.7", features = ["codec"], optional = true }

-[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "android"))'.dependencies]
+[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos", target_os = "android"))'.dependencies]
 nix = { version = "0.27", features = ["ioctl"] }

 [target.'cfg(target_os = "windows")'.dependencies]
diff --git a/src/platform/mod.rs b/src/platform/mod.rs
index 7bb628d..ac175ab 100644
--- a/src/platform/mod.rs
+++ b/src/platform/mod.rs
@@ -17,9 +17,9 @@
 #[cfg(unix)]
 pub mod posix;

-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 pub mod linux;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "freebsd"))]
 pub use self::linux::{create, Device, PlatformConfig};

 #[cfg(target_os = "macos")]
root@freebsd:/home/test/rust-tun # cargo check
    Checking tun2 v1.1.1 (/home/test/rust-tun)
error[E0432]: unresolved imports `libc::IFF_MULTI_QUEUE`, `libc::IFF_NO_PI`, `libc::IFF_TAP`, `libc::IFF_TUN`
  --> src/platform/linux/device.rs:16:44
   |
16 |     self, c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_RUNNING, IFF_TAP,
   |                                            ^^^^^^^^^^^^^^^  ^^^^^^^^^               ^^^^^^^ no `IFF_TAP` in the root
   |                                            |                |
   |                                            |                no `IFF_NO_PI` in the root
   |                                            no `IFF_MULTI_QUEUE` in the root
17 |     IFF_TUN, IFF_UP, IFNAMSIZ, O_RDWR, SOCK_DGRAM,
   |     ^^^^^^^ no `IFF_TUN` in the root
   |
help: a similar name exists in the module
   |
16 |     self, c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NOARP, IFF_RUNNING, IFF_TAP,
   |                                                             ~~~~~~~~~
help: a similar name exists in the module
   |
16 |     self, c_char, c_short, ifreq, AF_INET, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_RUNNING, IFF_UP,
   |                                                                                     ~~~~~~
help: a similar name exists in the module
   |
17 |     IFF_UP, IFF_UP, IFNAMSIZ, O_RDWR, SOCK_DGRAM,
   |     ~~~~~~

error[E0425]: cannot find value `TUN_PROTO_IP6` in this scope
  --> src/platform/posix/split.rs:52:25
   |
52 |             return Some(TUN_PROTO_IP6);
   |                         ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `TUN_PROTO_IP4` in this scope
  --> src/platform/posix/split.rs:54:25
   |
54 |             return Some(TUN_PROTO_IP4);
   |                         ^^^^^^^^^^^^^ not found in this scope

error[E0308]: mismatched types
  --> src/platform/linux/device.rs:94:39
   |
94 |               req.ifr_ifru.ifru_flags = device_type
   |  _____________-----------------------___^
   | |             |
   | |             expected due to the type of this binding
95 | |                 | if packet_information { 0 } else { iff_no_pi }
96 | |                 | if queues_num > 1 { iff_multi_queue } else { 0 };
   | |__________________________________________________________________^ expected `[i16; 2]`, found `i16`

error[E0609]: no field `ifru_newname` on type `__c_anonymous_ifr_ifru`
   --> src/platform/linux/device.rs:227:30
    |
227 |                 req.ifr_ifru.ifru_newname.as_mut_ptr(),
    |                              ^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `ifru_addr`, `ifru_dstaddr`, `ifru_broadaddr`, `ifru_buffer`, `ifru_flags` ... and 10 others

error[E0368]: binary assignment operation `|=` cannot be applied to type `[i16; 2]`
   --> src/platform/linux/device.rs:250:17
    |
250 |                 req.ifr_ifru.ifru_flags |= (IFF_UP | IFF_RUNNING) as c_short;
    |                 -----------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                 |
    |                 cannot use `|=` on type `[i16; 2]`

error[E0368]: binary assignment operation `&=` cannot be applied to type `[i16; 2]`
   --> src/platform/linux/device.rs:252:17
    |
252 |                 req.ifr_ifru.ifru_flags &= !(IFF_UP as c_short);
    |                 -----------------------^^^^^^^^^^^^^^^^^^^^^^^^
    |                 |
    |                 cannot use `&=` on type `[i16; 2]`

error[E0609]: no field `ifru_netmask` on type `__c_anonymous_ifr_ifru`
   --> src/platform/linux/device.rs:362:45
    |
362 |                 SockAddr::new(&req.ifr_ifru.ifru_netmask).map(Into::into)?,
    |                                             ^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `ifru_addr`, `ifru_dstaddr`, `ifru_broadaddr`, `ifru_buffer`, `ifru_flags` ... and 10 others

error[E0609]: no field `ifru_netmask` on type `__c_anonymous_ifr_ifru`
   --> src/platform/linux/device.rs:373:26
    |
373 |             req.ifr_ifru.ifru_netmask = SockAddr::from(value).into();
    |                          ^^^^^^^^^^^^ unknown field
    |
    = note: available fields are: `ifru_addr`, `ifru_dstaddr`, `ifru_broadaddr`, `ifru_buffer`, `ifru_flags` ... and 10 others

Some errors have detailed explanations: E0308, E0368, E0425, E0432, E0609.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `tun2` (lib) due to 9 previous errors

I am a bit busy with the investigation, but I have some plans to execute.

xmh0511 commented 4 months ago

For Freebsd, certain places need to be adjusted. In https://github.com/ssrlive/rust-tun/blob/v2/src/platform/posix/split.rs#L35, we should add some support, then write the specialized modules for Freebsd since it more or less has different APIs from Linux. Out of I don't have a Freebsd environment in hand, I couldn't implement it now.

xmh0511 commented 4 months ago

@SajjadPourali I searched the imported names in libc module that were reported as unresolved in your quote, I found that the libc for FreeBSD had at least IFF_UP, IFF_NOARP, and IFF_MULTI_QUEUE, see https://docs.rs/libc/0.2.153/x86_64-unknown-freebsd/libc/index.html?search=IFF_MULTI_QUEUE.

Do you try to update the dependencies and test them?

xmh0511 commented 4 months ago

@SajjadPourali @yurivict @M0dEx @ssrlive

This PR https://github.com/ssrlive/rust-tun/pull/51 prepares to fix this issue, which has made tun2 successfully compiled on FreeBSD. However, it cannot work due to Inappropriate ioctl for device, I still didn't find any resolution here. So, some help is needed to complete the patch.

The generated ioctl is by looking up https://github.com/lattera/freebsd/blob/master/sys/sys/sockio.h

Reference: https://github.com/osmocom/openggsn/blob/master/lib/tun.c

SajjadPourali commented 4 months ago

@xmh0511 I think in freebsd we should call SIOCAIFADDR to set an ip address, but in the code SIOCSIFADDR is used.

http://dostf.blogspot.com/2010/10/programmatic-interface-alias-creation.html

xmh0511 commented 4 months ago

@xmh0511 I think in freebsd we should call SIOCAIFADDR to set an ip address, but in the code SIOCSIFADDR is used.

http://dostf.blogspot.com/2010/10/programmatic-interface-alias-creation.html

I tried this scheme. However, it still cannot work

Error: Io(Os { code: 22, kind: InvalidInput, message: "Invalid argument" })

xmh0511 commented 4 months ago

Seems a relevant issue https://wiki.strongswan.org/issues/566

xmh0511 commented 4 months ago

The relevant resolution is http://fxr.watson.org/fxr/source/netinet/in_var.h?v=FREEBSD-13-STABLE;im=bigexc, and using SIOCAIFADDR

https://svnweb.freebsd.org/base/head/sbin/ifconfig/ifconfig.c?revision=281143&view=markup#l1012

xmh0511 commented 4 months ago

Now, tun2 has been available on FreeBSD. This issue can be closed as completed. Feel free to open new issue if there is some issue when using tun2 on FreeBSD.

xmh0511 commented 4 months ago

I found that the created tun interface remains in the resulting list of running the command ifconfig -a after the program exits on FreeBSD. The relevant is https://stackoverflow.com/questions/25600708/how-to-use-siocifdestroy-in-freebsd. However, it seems not to cause problems in my test.

Any enhancement to this "issue" is appreciated.

Running:

截屏2024-03-01 22 15 54

Exit:

截屏2024-03-01 22 16 35