NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/46633: create network cloned devices without specifying a unit
>Number: 46633
>Category: kern
>Synopsis: create clone network interface without unit
>Confidential: yes
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed Jun 27 11:45:00 +0000 2012
>Originator: Darren Reed
>Release: NetBSD 5.99.59
>Organization:
NetBSD
>Environment:
>Description:
The ifconfig command currently requires that network devices that support
cloning be created by specifying the unit number when ifconfig is run.
This requires the caller of ifconfig to have somehow decided that the
unit number to be used to have already been allocated. This change removes
that need.
Whereas in the past a script was required to create an interface
like this:
# ifconfig gif0 create
the following will now work:
# ifconfig gif create
gif0
>How-To-Repeat:
Create a cloned network interface.
>Fix:
--- usr/src/sys/net/if.h.dist 2011-10-26 10:00:24.000000000 +0200
+++ usr/src/sys/net/if.h 2012-06-27 12:53:11.000000000 +0200
@@ -905,7 +905,7 @@
void if_clone_attach(struct if_clone *);
void if_clone_detach(struct if_clone *);
-int if_clone_create(const char *);
+int if_clone_create(const char *, char *, int);
int if_clone_destroy(const char *);
int ifq_enqueue(struct ifnet *, struct mbuf * ALTQ_COMMA
--- usr/src/sys/net/if.c.dist 2011-11-27 22:42:44.000000000 +0100
+++ usr/src/sys/net/if.c 2012-06-27 13:27:36.000000000 +0200
@@ -154,6 +154,7 @@
static int if_rt_walktree(struct rtentry *, void *);
+static struct if_clone *if_clone_find(const char *, const int);
static struct if_clone *if_clone_lookup(const char *, int *);
static int if_clone_list(struct if_clonereq *);
@@ -927,15 +928,52 @@
return ERESTART;
}
+static struct if_clone *
+if_clone_find(const char *name, const int len)
+{
+ struct if_clone *ifc;
+
+ LIST_FOREACH(ifc, &if_cloners, ifc_list) {
+ if (strlen(ifc->ifc_name) == len &&
+ strncmp(name, ifc->ifc_name, len) == 0)
+ return ifc;
+ }
+
+ return NULL;
+}
+
/*
* Create a clone network interface.
*/
int
-if_clone_create(const char *name)
+if_clone_create(const char *name, char *newname, int dynamic)
{
+ char buffer[IFNAMSIZ];
struct if_clone *ifc;
int unit;
+ if (dynamic == 1) {
+ /*
+ * If "name" is the name of a device that supports cloning
+ * and thus excludes a unit number and the dynamic flag is
+ * set then attempt to allocate a unit number, construct
+ * the name for the new device and return it in newname.
+ * The assumption is newname is at least IFNAMSIZ in length.
+ */
+ ifc = if_clone_find(name, strlen(name));
+ if (newname != NULL && ifc != NULL) {
+ for (unit = 0; unit < INT_MAX / 10; unit++) {
+ snprintf(buffer, IFNAMSIZ, "%s%d",
+ name, unit);
+ if (ifunit(buffer) == NULL) {
+ strlcpy(newname, buffer, IFNAMSIZ);
+ return (*ifc->ifc_create)(ifc, unit);
+ }
+ }
+ return EINVAL;
+ }
+ }
+
ifc = if_clone_lookup(name, &unit);
if (ifc == NULL)
return EINVAL;
@@ -988,12 +1026,7 @@
if (cp == name || cp - name == IFNAMSIZ || !*cp)
return NULL; /* No name or unit number */
- LIST_FOREACH(ifc, &if_cloners, ifc_list) {
- if (strlen(ifc->ifc_name) == cp - name &&
- strncmp(name, ifc->ifc_name, cp - name) == 0)
- break;
- }
-
+ ifc = if_clone_find(name, cp - name);
if (ifc == NULL)
return NULL;
@@ -1776,6 +1809,7 @@
switch (cmd) {
case SIOCIFCREATE:
+ case OSIOCIFCREATE:
case SIOCIFDESTROY:
if (l != NULL) {
error = kauth_authorize_network(l->l_cred,
@@ -1785,9 +1819,11 @@
if (error != 0)
return error;
}
- return (cmd == SIOCIFCREATE) ?
- if_clone_create(ifr->ifr_name) :
- if_clone_destroy(ifr->ifr_name);
+ if (cmd == OSIOCIFCREATE)
+ return if_clone_create(ifr->ifr_name, NULL, 0);
+ if (cmd == SIOCIFDESTROY)
+ return if_clone_destroy(ifr->ifr_name);
+ return if_clone_create(ifr->ifr_name, ifr->ifr_name, 1);
case SIOCIFGCLONERS:
return if_clone_list((struct if_clonereq *)data);
--- usr/src/sbin/ifconfig/util.c.dist 2010-12-14 08:52:22.000000000 +0100
+++ usr/src/sbin/ifconfig/util.c 2012-06-27 13:20:59.000000000 +0200
@@ -230,13 +230,19 @@
int
indirect_ioctl(prop_dictionary_t env, unsigned long cmd, void *data)
{
+ struct ifreq oifr;
struct ifreq ifr;
+ int error;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_data = data;
+ oifr = ifr;
- return direct_ioctl(env, cmd, &ifr);
+ error = direct_ioctl(env, cmd, &ifr);
+ if (error == 0 && strncmp(ifr.ifr_name, oifr.ifr_name, IFNAMSIZ))
+ printf("%s\n", ifr.ifr_name);
+ return error;
}
void
--- usr/src/sbin/ifconfig/ifconfig.8.dist 2012-06-27 13:42:23.000000000
+0200
+++ usr/src/sbin/ifconfig/ifconfig.8 2012-06-27 13:42:15.000000000 +0200
@@ -530,7 +530,9 @@
interfaces previously configured with
.Cm tunnel .
.It Cm create
-Create the specified network pseudo-device.
+Create the specified network pseudo-device. When used without a unit
+number for the network interface, the kernel will allocate a unit and
+the full interface name is printed on stdout before the program exits.
.It Cm destroy
Destroy the specified network pseudo-device.
.It Cm pltime Ar n
Home |
Main Index |
Thread Index |
Old Index