git: 03f7680517c8 - stable/14 - if_enc(4): Use new KPI to create enc interface
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 20 Oct 2024 13:43:43 UTC
The branch stable/14 has been updated by zlei:
URL: https://cgit.FreeBSD.org/src/commit/?id=03f7680517c88ec9b656f73e5382bcaf07791d2c
commit 03f7680517c88ec9b656f73e5382bcaf07791d2c
Author: Zhenlei Huang <zlei@FreeBSD.org>
AuthorDate: 2024-06-27 09:22:37 +0000
Commit: Zhenlei Huang <zlei@FreeBSD.org>
CommitDate: 2024-10-20 13:43:01 +0000
if_enc(4): Use new KPI to create enc interface
This driver allows only exactly one instance to be created. Clone
creating additional interfaces, e.g. `ifconfig enc1 create`, will get
error EEXIST which is somewhat confusing.
Convert to new KPI for less confusing error ENOSPC.
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D45758
(cherry picked from commit eacad82f3ad0af7d74968e73ed383fc4531d1924)
---
sys/net/if_enc.c | 46 +++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c
index 3c7ae38324c3..3c3f19661063 100644
--- a/sys/net/if_enc.c
+++ b/sys/net/if_enc.c
@@ -94,8 +94,9 @@ VNET_DEFINE_STATIC(struct if_clone *, enc_cloner);
static int enc_ioctl(struct ifnet *, u_long, caddr_t);
static int enc_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);
-static int enc_clone_create(struct if_clone *, int, caddr_t);
-static void enc_clone_destroy(struct ifnet *);
+static int enc_clone_create(struct if_clone *, char *, size_t,
+ struct ifc_data *, struct ifnet **);
+static int enc_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
static void enc_add_hhooks(struct enc_softc *);
static void enc_remove_hhooks(struct enc_softc *);
@@ -139,11 +140,14 @@ SYSCTL_INT(_net_enc_out, OID_AUTO, ipsec_bpf_mask,
CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(bpf_mask_out), 0,
"IPsec output bpf mask");
-static void
-enc_clone_destroy(struct ifnet *ifp)
+static int
+enc_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
{
struct enc_softc *sc;
+ if (ifp->if_dunit == 0 && (flags & IFC_F_FORCE) == 0)
+ return (EINVAL);
+
sc = ifp->if_softc;
KASSERT(sc == V_enc_sc, ("sc != ifp->if_softc"));
@@ -151,31 +155,26 @@ enc_clone_destroy(struct ifnet *ifp)
if_detach(ifp);
if_free(ifp);
free(sc, M_DEVBUF);
- V_enc_sc = NULL;
+ return (0);
}
static int
-enc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+enc_clone_create(struct if_clone *ifc, char *name, size_t len,
+ struct ifc_data *ifd, struct ifnet **ifpp)
{
struct ifnet *ifp;
struct enc_softc *sc;
- sc = malloc(sizeof(struct enc_softc), M_DEVBUF,
- M_WAITOK | M_ZERO);
+ sc = malloc(sizeof(struct enc_softc), M_DEVBUF, M_WAITOK | M_ZERO);
ifp = sc->sc_ifp = if_alloc(IFT_ENC);
- if (V_enc_sc != NULL) {
- if_free(ifp);
- free(sc, M_DEVBUF);
- return (EEXIST);
- }
- V_enc_sc = sc;
- if_initname(ifp, encname, unit);
+ if_initname(ifp, encname, ifd->unit);
ifp->if_mtu = ENCMTU;
ifp->if_ioctl = enc_ioctl;
ifp->if_output = enc_output;
ifp->if_softc = sc;
if_attach(ifp);
bpfattach(ifp, DLT_ENC, sizeof(struct enchdr));
+ *ifpp = ifp;
return (0);
}
@@ -375,10 +374,18 @@ enc_remove_hhooks(struct enc_softc *sc)
static void
vnet_enc_init(const void *unused __unused)
{
+ struct ifnet *ifp;
- V_enc_sc = NULL;
- V_enc_cloner = if_clone_simple(encname, enc_clone_create,
- enc_clone_destroy, 1);
+ struct if_clone_addreq req = {
+ .create_f = enc_clone_create,
+ .destroy_f = enc_clone_destroy,
+ .flags = IFC_F_AUTOUNIT | IFC_F_LIMITUNIT,
+ .maxunit = 0,
+ };
+ V_enc_cloner = ifc_attach_cloner(encname, &req);
+ struct ifc_data ifd = { .unit = 0 };
+ ifc_create_ifp(encname, &ifd, &ifp);
+ V_enc_sc = ifp->if_softc;
}
VNET_SYSINIT(vnet_enc_init, SI_SUB_PSEUDO, SI_ORDER_ANY,
vnet_enc_init, NULL);
@@ -398,7 +405,8 @@ vnet_enc_uninit(const void *unused __unused)
{
KASSERT(V_enc_sc != NULL, ("%s: V_enc_sc is %p\n", __func__, V_enc_sc));
- if_clone_detach(V_enc_cloner);
+ ifc_detach_cloner(V_enc_cloner);
+ V_enc_sc = NULL;
}
VNET_SYSUNINIT(vnet_enc_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
vnet_enc_uninit, NULL);