if_ovpn(4): implement ioctl() to set if_flags

Fully working openvpn(8) --iroute support needs real subnet config
on ovpn(4) interfaces (IFF_BROADCAST), while client-side/p2p
configs need IFF_POINTOPOINT setting.  So make this configurable.

Reviewed by:	kp
This commit is contained in:
Gert Doering 2022-10-12 15:30:07 +02:00 committed by Kristof Provost
parent 3c3b906b54
commit 2e797555f7
2 changed files with 43 additions and 0 deletions

View File

@ -1081,6 +1081,45 @@ ovpn_set_peer(struct ifnet *ifp, const nvlist_t *nvl)
return (0);
}
static int
ovpn_set_ifmode(struct ifnet *ifp, const nvlist_t *nvl)
{
struct ovpn_softc *sc = ifp->if_softc;
int ifmode;
if (nvl == NULL)
return (EINVAL);
if (! nvlist_exists_number(nvl, "ifmode") )
return (EINVAL);
ifmode = nvlist_get_number(nvl, "ifmode");
OVPN_WLOCK(sc);
/* deny this if UP */
if (ifp->if_flags & IFF_UP) {
OVPN_WUNLOCK(sc);
return (EBUSY);
}
switch (ifmode & ~IFF_MULTICAST) {
case IFF_POINTOPOINT:
case IFF_BROADCAST:
ifp->if_flags &=
~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
ifp->if_flags |= ifmode;
break;
default:
OVPN_WUNLOCK(sc);
return (EINVAL);
}
OVPN_WUNLOCK(sc);
return (0);
}
static int
ovpn_ioctl_set(struct ifnet *ifp, struct ifdrv *ifd)
{
@ -1135,6 +1174,9 @@ ovpn_ioctl_set(struct ifnet *ifp, struct ifdrv *ifd)
case OVPN_SET_PEER:
ret = ovpn_set_peer(ifp, nvl);
break;
case OVPN_SET_IFMODE:
ret = ovpn_set_ifmode(ifp, nvl);
break;
default:
ret = ENOTSUP;
}

View File

@ -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