mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 04:22:44 +00:00
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
This commit is contained in:
parent
a1cfe4c764
commit
a2cac544a6
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user