/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
static int if_rtmtu(struct radix_node *, void *);
static void if_rtmtu_update(struct ifnet *);
-static struct if_clone *if_clone_lookup(const char *, int *);
#if IF_CLONE_LIST
static int if_clone_list(int count, int * total, user_addr_t dst);
#endif /* IF_CLONE_LIST */
extern void nd6_setmtu(struct ifnet *);
#endif
-#define M_CLONE M_IFADDR
/*
* Network interface utility routines.
* Create a clone network interface.
*/
static int
-if_clone_create(char *name, int len)
+if_clone_create(char *name, int len, void *params)
{
struct if_clone *ifc;
char *dp;
- int wildcard, bytoff, bitoff;
- int unit;
+ int wildcard;
+ u_int32_t bytoff, bitoff;
+ u_int32_t unit;
int err;
ifc = if_clone_lookup(name, &unit);
return (EEXIST);
bytoff = bitoff = 0;
- wildcard = (unit < 0);
+ wildcard = (unit == UINT32_MAX);
/*
* Find a free unit if none was given.
*/
if (unit > ifc->ifc_maxunit)
return (ENXIO);
- err = (*ifc->ifc_create)(ifc, unit);
+ err = (*ifc->ifc_create)(ifc, unit, params);
if (err != 0)
return (err);
struct if_clone *ifc;
struct ifnet *ifp;
int bytoff, bitoff;
- int unit;
+ u_int32_t unit;
ifc = if_clone_lookup(name, &unit);
if (ifc == NULL)
* Look up a network interface cloner.
*/
-static struct if_clone *
-if_clone_lookup(const char *name, int *unitp)
+__private_extern__ struct if_clone *
+if_clone_lookup(const char *name, u_int32_t *unitp)
{
struct if_clone *ifc;
const char *cp;
found_name:
if (*cp == '\0') {
- i = -1;
+ i = 0xffff;
} else {
for (i = 0; *cp != '\0'; cp++) {
if (*cp < '0' || *cp > '9') {
int bytoff, bitoff;
int err;
int len, maxclone;
- int unit;
+ u_int32_t unit;
KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit,
("%s: %s requested more units then allowed (%d > %d)",
if_cloners_count++;
for (unit = 0; unit < ifc->ifc_minifs; unit++) {
- err = (*ifc->ifc_create)(ifc, unit);
+ err = (*ifc->ifc_create)(ifc, unit, NULL);
KASSERT(err == 0,
("%s: failed to create required interface %s%d",
__func__, ifc->ifc_name, unit));
ifr = (struct ifreq *)data;
switch (cmd) {
case SIOCIFCREATE:
+ case SIOCIFCREATE2:
+ error = proc_suser(p);
+ if (error)
+ return (error);
+ return if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name),
+ cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL);
case SIOCIFDESTROY:
error = proc_suser(p);
if (error)
return (error);
- return ((cmd == SIOCIFCREATE) ?
- if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
- if_clone_destroy(ifr->ifr_name));
+ return if_clone_destroy(ifr->ifr_name);
#if IF_CLONE_LIST
case SIOCIFGCLONERS32: {
struct if_clonereq32 *ifcr = (struct if_clonereq32 *)data;
ifr->ifr_wake_flags = ifnet_get_wake_flags(ifp);
ifnet_lock_done(ifp);
break;
-
+
+ case SIOCGIFGETRTREFCNT:
+#if IFNET_ROUTE_REFCNT
+ ifnet_lock_shared(ifp);
+ ifr->ifr_route_refcnt = ifp->if_route_refcnt;
+ ifnet_lock_done(ifp);
+ break;
+#else
+ return (EOPNOTSUPP);
+#endif /* IFNET_ROUTE_REFCNT */
+
default:
oif_flags = ifp->if_flags;
if (so->so_proto == 0)