aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/if_ovpn.c42
-rw-r--r--sys/net/if_ovpn.h1
2 files changed, 43 insertions, 0 deletions
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 524640639e76..14634cfc969b 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -1082,6 +1082,45 @@ ovpn_set_peer(struct ifnet *ifp, const nvlist_t *nvl)
}
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)
{
struct ovpn_softc *sc = ifp->if_softc;
@@ -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;
}
diff --git a/sys/net/if_ovpn.h b/sys/net/if_ovpn.h
index 26a9907711ce..fd1c21e70435 100644
--- a/sys/net/if_ovpn.h
+++ b/sys/net/if_ovpn.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