git: a2cac544a668 - main - if_clone: Allow maxunit to be zero
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 03 Jul 2024 13:20:19 UTC
The branch main has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=a2cac544a668d2834ed41986aca32b44b9819c89 commit a2cac544a668d2834ed41986aca32b44b9819c89 Author: Zhenlei Huang <zlei@FreeBSD.org> AuthorDate: 2024-07-03 13:14:08 +0000 Commit: Zhenlei Huang <zlei@FreeBSD.org> CommitDate: 2024-07-03 13:14:08 +0000 if_clone: Allow maxunit to be zero Some drivers, e.g. if_enc(4), only allow one instance to be created, but the KPI ifc_attach_cloner() treat zero value of maxunit as not limited, aka IF_MAXUNIT. Introduce a new flag IFC_F_LIMITUNIT to indicate that the requested maxunit is limited and should be respected. Consumers should use the new flag if there is an intended limit. Reviewed by: glebius MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D45757 --- sys/net/if_clone.c | 13 +++++++++---- sys/net/if_clone.h | 5 +++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 8f1bad56d14e..13d89e4e2c59 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -483,12 +483,13 @@ if_clone_alloc(const char *name, int maxunit) struct if_clone *ifc; KASSERT(name != NULL, ("%s: no name\n", __func__)); + MPASS(maxunit >= 0); ifc = malloc(sizeof(struct if_clone), M_CLONE, M_WAITOK | M_ZERO); strncpy(ifc->ifc_name, name, IFCLOSIZ-1); IF_CLONE_LOCK_INIT(ifc); IF_CLONE_ADDREF(ifc); - ifc->ifc_maxunit = maxunit ? maxunit : IF_MAXUNIT; + ifc->ifc_maxunit = maxunit; ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx); LIST_INIT(&ifc->ifc_iflist); @@ -521,12 +522,16 @@ if_clone_attach(struct if_clone *ifc) struct if_clone * ifc_attach_cloner(const char *name, struct if_clone_addreq *req) { + int maxunit; + struct if_clone *ifc; + if (req->create_f == NULL || req->destroy_f == NULL) return (NULL); if (strnlen(name, IFCLOSIZ) >= (IFCLOSIZ - 1)) return (NULL); - struct if_clone *ifc = if_clone_alloc(name, req->maxunit); + maxunit = (req->flags & IFC_F_LIMITUNIT) ? req->maxunit : IF_MAXUNIT; + ifc = if_clone_alloc(name, maxunit); ifc->ifc_match = req->match_f != NULL ? req->match_f : ifc_simple_match; ifc->ifc_create = req->create_f; ifc->ifc_destroy = req->destroy_f; @@ -584,7 +589,7 @@ if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match, { struct if_clone *ifc; - ifc = if_clone_alloc(name, maxunit); + ifc = if_clone_alloc(name, maxunit ? maxunit : IF_MAXUNIT); ifc->ifc_match = match; ifc->ifc_create = ifc_advanced_create_wrapper; ifc->ifc_destroy = ifc_advanced_destroy_wrapper; @@ -629,7 +634,7 @@ if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy, struct if_clone *ifc; u_int unit; - ifc = if_clone_alloc(name, 0); + ifc = if_clone_alloc(name, IF_MAXUNIT); ifc->ifc_match = ifc_simple_match; ifc->ifc_create = ifc_simple_create_wrapper; ifc->ifc_destroy = ifc_simple_destroy_wrapper; diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h index 45a6d4144230..e11fc5c8cdd7 100644 --- a/sys/net/if_clone.h +++ b/sys/net/if_clone.h @@ -101,6 +101,11 @@ struct if_clone_addreq_v2 { #define IFC_F_SYSSPACE 0x04 /* Cloner callback: params pointer is in kernel memory */ #define IFC_F_FORCE 0x08 /* Deletion flag: force interface deletion */ #define IFC_F_CREATE 0x10 /* Creation flag: indicate creation request */ +#define IFC_F_LIMITUNIT 0x20 /* Creation flag: the unit number is limited */ + +_Static_assert(offsetof(struct if_clone_addreq, destroy_f) == + offsetof(struct if_clone_addreq_v2, destroy_f), + "destroy_f in if_clone_addreq and if_clone_addreq_v2 are at different offset"); struct if_clone *ifc_attach_cloner(const char *name, struct if_clone_addreq *req); void ifc_detach_cloner(struct if_clone *ifc);