git: 2e797555f701 - main - if_ovpn(4): implement ioctl() to set if_flags

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 17 Oct 2022 13:58:23 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=2e797555f701c38d9d82cbbea61d3d8933f2bd56

commit 2e797555f701c38d9d82cbbea61d3d8933f2bd56
Author:     Gert Doering <gert@greenie.muc.de>
AuthorDate: 2022-10-12 13:30:07 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-10-17 13:33:45 +0000

    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
---
 sys/net/if_ovpn.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 sys/net/if_ovpn.h |  1 +
 2 files changed, 43 insertions(+)

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