Skip to content

Commit

Permalink
Allow to set ifmode for existing DCO interfaces in FreeBSD
Browse files Browse the repository at this point in the history
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 <franco@opnsense.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <AE20A784-506C-488B-9302-2D3AE775B168@opnsense.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28688.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
  • Loading branch information
fichtner authored and cron2 committed Jun 2, 2024
1 parent fbe3b49 commit 82036c1
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions src/openvpn/dco_freebsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
}

Expand All @@ -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
Expand Down

0 comments on commit 82036c1

Please sign in to comment.