svn commit: r277118 - projects/ifnet/sys/net
Gleb Smirnoff
glebius at FreeBSD.org
Tue Jan 13 08:24:39 UTC 2015
Author: glebius
Date: Tue Jan 13 08:24:37 2015
New Revision: 277118
URL: https://svnweb.freebsd.org/changeset/base/277118
Log:
- Allow drivers to specify a if_cloner for unit allocation.
- Allow drivers to specify a specific name when attaching an interface.
Sponsored by: Nginx, Inc.
Modified:
projects/ifnet/sys/net/if.c
projects/ifnet/sys/net/if.h
projects/ifnet/sys/net/if_mib.c
projects/ifnet/sys/net/if_var.h
Modified: projects/ifnet/sys/net/if.c
==============================================================================
--- projects/ifnet/sys/net/if.c Tue Jan 13 07:49:47 2015 (r277117)
+++ projects/ifnet/sys/net/if.c Tue Jan 13 08:24:37 2015 (r277118)
@@ -492,6 +492,9 @@ ifdriver_bless(struct ifdriver *ifdrv, s
* Allocate a struct ifnet and an index for an interface. A layer 2
* common structure will also be allocated if an allocation routine is
* registered for the passed type.
+ *
+ * The only reason for this function to fail is failure to allocate a
+ * unit number, which is possible only if driver does cloning.
*/
if_t
if_attach(struct if_attach_args *ifat)
@@ -507,6 +510,23 @@ if_attach(struct if_attach_args *ifat)
("%s: version %d, expected %d",
__func__, ifat->ifat_version, IF_ATTACH_VERSION));
+ ifdrv = ifat->ifat_drv;
+ ift = iftype_find(ifdrv->ifdrv_type);
+ if ((ifdrv->ifdrv_flags & IFDRV_BLESSED) == 0)
+ ifdriver_bless(ifdrv, ift);
+
+ if (ifdrv->ifdrv_clone != NULL) {
+ int error;
+
+ error = ifc_alloc_unit(ifdrv->ifdrv_clone, &ifat->ifat_dunit);
+ if (error) {
+ log(LOG_WARNING, "%s unit allocation failure: %d\n",
+ ifdrv->ifdrv_name, error);
+ ifat->ifat_error = error;
+ return (NULL);
+ }
+ }
+
ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK | M_ZERO);
for (int i = 0; i < IFCOUNTERS; i++)
ifp->if_counters[i] = counter_u64_alloc(M_WAITOK);
@@ -515,12 +535,6 @@ if_attach(struct if_attach_args *ifat)
mac_ifnet_create(ifp);
#endif
- ifdrv = ifat->ifat_drv;
- ift = iftype_find(ifdrv->ifdrv_type);
-
- if ((ifdrv->ifdrv_flags & IFDRV_BLESSED) == 0)
- ifdriver_bless(ifdrv, ift);
-
ifp->if_ops = &ifdrv->ifdrv_ops;
ifp->if_drv = ifdrv;
ifp->if_type = ift;
@@ -564,7 +578,9 @@ if_attach(struct if_attach_args *ifat)
/* XXXGL: there is no check that name is unique. */
ifp->if_dunit = ifat->ifat_dunit;
- if (ifat->ifat_dunit != IF_DUNIT_NONE)
+ if (ifat->ifat_name)
+ strlcpy(ifp->if_xname, ifat->ifat_name, IFNAMSIZ);
+ else if (ifat->ifat_dunit != IFAT_DUNIT_NONE)
snprintf(ifp->if_xname, IFNAMSIZ, "%s%d",
ifdrv->ifdrv_name, ifat->ifat_dunit);
else
@@ -918,6 +934,9 @@ if_detach(if_t ifp)
ifindex_free(ifp->if_index);
IFNET_WUNLOCK();
+ if (ifp->if_drv->ifdrv_clone != NULL)
+ ifc_free_unit(ifp->if_drv->ifdrv_clone, ifp->if_dunit);
+
if (refcount_release(&ifp->if_refcount))
if_free_internal(ifp);
CURVNET_RESTORE();
Modified: projects/ifnet/sys/net/if.h
==============================================================================
--- projects/ifnet/sys/net/if.h Tue Jan 13 07:49:47 2015 (r277117)
+++ projects/ifnet/sys/net/if.h Tue Jan 13 08:24:37 2015 (r277118)
@@ -648,6 +648,7 @@ struct ifdriver {
* static string works well.
*/
const char * ifdrv_name;
+ struct if_clone *ifdrv_clone;
ifType ifdrv_type; /* from if_types.h */
uint8_t ifdrv_hdrlen; /* media header length */
uint8_t ifdrv_addrlen; /* media address length */
@@ -671,11 +672,14 @@ struct if_attach_args {
uint8_t ifat_spare8;
uint16_t ifat_spare16;
uint32_t ifat_spare32;
+ int ifat_error; /* Filled on return. */
struct ifdriver *ifat_drv;
void *ifat_softc; /* Driver private softc. */
const uint8_t *ifat_lla; /* Link-level address. */
- int32_t ifat_dunit; /* unit or IF_DUNIT_NONE */
+ int32_t ifat_dunit; /* Specific unit or a hint. */
+#define IFAT_DUNIT_NONE (-1)
+ char * ifat_name; /* If driver wants a specific name. */
/*
* Variables that may differ between two instances of a same
* driver, but are constant within instance lifetime.
Modified: projects/ifnet/sys/net/if_mib.c
==============================================================================
--- projects/ifnet/sys/net/if_mib.c Tue Jan 13 07:49:47 2015 (r277117)
+++ projects/ifnet/sys/net/if_mib.c Tue Jan 13 08:24:37 2015 (r277118)
@@ -129,7 +129,7 @@ sysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XX
error = ENOMEM;
goto out;
}
- if (ifp->if_dunit == IF_DUNIT_NONE)
+ if (ifp->if_dunit == IFAT_DUNIT_NONE)
strcpy(dbuf, ifp->if_drv->ifdrv_name);
else
sprintf(dbuf, "%s%d", ifp->if_drv->ifdrv_name,
Modified: projects/ifnet/sys/net/if_var.h
==============================================================================
--- projects/ifnet/sys/net/if_var.h Tue Jan 13 07:49:47 2015 (r277117)
+++ projects/ifnet/sys/net/if_var.h Tue Jan 13 08:24:37 2015 (r277118)
@@ -53,9 +53,6 @@ struct netmap_adapter;
#include <sys/rwlock.h> /* XXX */
#include <sys/sx.h> /* XXX */
#include <sys/_task.h> /* if_link_task */
-
-#define IF_DUNIT_NONE -1
-
#include <altq/if_altq.h>
TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */
More information about the svn-src-projects
mailing list