Signed-off-by:  Kristof Provost <kprov...@netgate.com>

On 12 Oct 2022, at 16:59, Gert Doering wrote:

> To be able to configure a FreeBSD interface to "subnet" mode
> (as opposed to point-to-point mode), it needs to have its
> if_iflags set to IFF_BROADCAST.  For tun(4) interface this is
> done with the TUNSIFMODE ioctl(), but this does not work for
> more modern interfaces like ovpn(4) which communicate over
> a common SIOCSDRVSPEC ioctl() that contains a "cmd" and a
> "parameter list".
>
> Introduce OVPN_SET_IFMODE cmd, add dco_set_ifmode() function
> to put kernel interface into IFF_BROADCAST or IFF_POINTOPOINT
> as needed.
>
> (This needs a kernel patch to add the OVPN_SET_IFMODE on the
> other side - with an older kernel, OpenVPN will just fail now)
>
> Signed-off-by: Gert Doering <g...@greenie.muc.de>
> ---
>  src/openvpn/dco_freebsd.c      | 36 ++++++++++++++++++++++++++++++++++
>  src/openvpn/ovpn_dco_freebsd.h |  1 +
>  2 files changed, 37 insertions(+)
>
> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
> index c6da6ce3..8adbf7f1 100644
> --- a/src/openvpn/dco_freebsd.c
> +++ b/src/openvpn/dco_freebsd.c
> @@ -165,6 +165,34 @@ ovpn_dco_init(int mode, dco_context_t *dco)
>      return true;
>  }
>
> +static int
> +dco_set_ifmode(dco_context_t *dco, int ifmode)
> +{
> +    struct ifdrv drv;
> +    nvlist_t *nvl;
> +    int ret;
> +
> +    msg(M_INFO, "ifmode=%08x", ifmode);
> +    nvl = nvlist_create(0);
> +    nvlist_add_number(nvl, "ifmode", ifmode);
> +
> +    CLEAR(drv);
> +    snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
> +    drv.ifd_cmd = OVPN_SET_IFMODE;
> +    drv.ifd_data = nvlist_pack(nvl, &drv.ifd_len);
> +
> +    ret = ioctl(dco->fd, SIOCSDRVSPEC, &drv);
> +    if (ret)
> +    {
> +        msg(M_WARN | M_ERRNO, "Failed to set ifmode");
> +    }
> +
> +    free(drv.ifd_data);
> +    nvlist_destroy(nvl);
> +
> +    return ret;
> +}
> +
>  static int
>  create_interface(struct tuntap *tt, const char *dev)
>  {
> @@ -205,6 +233,14 @@ create_interface(struct tuntap *tt, const char *dev)
>      snprintf(tt->dco.ifname, IFNAMSIZ, "%s", ifr.ifr_data);
>      tt->actual_name = string_alloc(tt->dco.ifname, NULL);
>
> +    /* 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;
>  }
>
> diff --git a/src/openvpn/ovpn_dco_freebsd.h b/src/openvpn/ovpn_dco_freebsd.h
> index 7ceec06e..cf92d597 100644
> --- a/src/openvpn/ovpn_dco_freebsd.h
> +++ b/src/openvpn/ovpn_dco_freebsd.h
> @@ -60,5 +60,6 @@ enum ovpn_key_cipher {
>  #define OVPN_SEND_PKT           _IO('D', 9)
>  #define OVPN_POLL_PKT           _IO('D', 10)
>  #define OVPN_GET_PKT            _IO('D', 11)
> +#define OVPN_SET_IFMODE         _IO('D', 12)
>
>  #endif /* ifndef _NET_IF_OVPN_H_ */
> -- 
> 2.37.3
>
>
>
> _______________________________________________
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel


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

Reply via email to