]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/if.c
xnu-1504.7.4.tar.gz
[apple/xnu.git] / bsd / net / if.c
index 43b96dfffba096042ed77617cd58e41d57132237..02b698007897c6f6b6ac4a24534fcc34c338f430 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -132,7 +132,6 @@ void if_rtproto_del(struct ifnet *ifp, int protocol);
 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 */
@@ -157,7 +156,6 @@ static struct ifaddr *ifa_ifwithnet_common(const struct sockaddr *,
 extern void    nd6_setmtu(struct ifnet *);
 #endif
 
-#define M_CLONE                M_IFADDR
 
 /*
  * Network interface utility routines.
@@ -287,12 +285,13 @@ if_next_index(void)
  * 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);
@@ -303,7 +302,7 @@ if_clone_create(char *name, int len)
                return (EEXIST);
 
        bytoff = bitoff = 0;
-       wildcard = (unit < 0);
+       wildcard = (unit == UINT32_MAX);
        /*
         * Find a free unit if none was given.
         */
@@ -321,7 +320,7 @@ if_clone_create(char *name, int len)
        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);
 
@@ -364,7 +363,7 @@ if_clone_destroy(const char *name)
        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)
@@ -397,8 +396,8 @@ if_clone_destroy(const char *name)
  * 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;
@@ -419,7 +418,7 @@ if_clone_lookup(const char *name, int *unitp)
 
  found_name:
        if (*cp == '\0') {
-               i = -1;
+               i = 0xffff;
        } else {
                for (i = 0; *cp != '\0'; cp++) {
                        if (*cp < '0' || *cp > '9') {
@@ -444,7 +443,7 @@ if_clone_attach(struct if_clone *ifc)
        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)",
@@ -467,7 +466,7 @@ if_clone_attach(struct if_clone *ifc)
        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));
@@ -1182,13 +1181,17 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
        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;
@@ -1459,7 +1462,17 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
                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)