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