While prexisting devices work well TUN/TAP the DCO interfaces require
setting the ifmode which cannot be done by FreeBSD base tooling.  In
peer-to-peer mode this is not a problem because that is the default mode.
Subnet mode, however, will fail to be set and the resulting connection does
not start:

  Failed to create interface ovpns2 (SIOCSIFNAME): File exists (errno=17)
  DCO device ovpns2 already exists, won't be destroyed at shutdown
  /sbin/ifconfig ovpns2 10.1.8.1/24 mtu 1500 up
  ifconfig: in_exec_nl(): Empty IFA_LOCAL/IFA_ADDRESS
  ifconfig: ioctl (SIOCAIFADDR): Invalid argument
  FreeBSD ifconfig failed: external program exited with error status: 1
  Exiting due to fatal error

Slightly restructure the code to catch the specific error
condition and execute dco_set_ifmode() in this case as well.

Signed-off-by: Franco Fichtner <fra...@opnsense.org>
---
 src/openvpn/dco_freebsd.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 577c65f8..7c8b29c9 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -219,6 +219,9 @@ create_interface(struct tuntap *tt, const char *dev)
     {
         ifr.ifr_data = (char *)dev;
     }
+
+    snprintf(tt->dco.ifname, IFNAMSIZ, "%s", ifr.ifr_data);
+
     ret = ioctl(tt->dco.fd, SIOCSIFNAME, &ifr);
     if (ret)
     {
@@ -229,16 +232,6 @@ create_interface(struct tuntap *tt, const char *dev)
         return ret;
     }
  -    snprintf(tt->dco.ifname, IFNAMSIZ, "%s", ifr.ifr_data);
-
-    /* see "Interface Flags" in ifnet(9) */
-    int i = IFF_POINTOPOINT | IFF_MULTICAST;
-    if (tt->topology == TOP_SUBNET)
-    {
-        i = IFF_BROADCAST | IFF_MULTICAST;
-    }
-    dco_set_ifmode(&tt->dco, i);
-
     return 0;
 }
  @@ -265,7 +258,20 @@ remove_interface(struct tuntap *tt)
 int
 open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
 {
-    return create_interface(tt, dev);
+    int ret = create_interface(tt, dev);
+
+    if (ret >= 0 || ret == -EEXIST)
+    {
+        /* see "Interface Flags" in ifnet(9) */
+        int i = IFF_POINTOPOINT | IFF_MULTICAST;
+        if (tt->topology == TOP_SUBNET)
+        {
+            i = IFF_BROADCAST | IFF_MULTICAST;
+        }
+        dco_set_ifmode(&tt->dco, i);
+    }
+
+    return ret;
 }
   void


_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to