Sam Leffler wrote:
Sam Leffler wrote:
I think the attached patch against HEAD DTRT. Should work on RELENG_7 too.

Never mind; this has some issues. I'll post another patch after I do some real testing.


Try this. It does as a I suggested--on seeing the first cmd line arg that is not marked as a cloning parameter the callback is done and state is updated. Still too hackish for my taste but to handle this and other similar stuff "properly" requires a significant overhaul (there have been too many hands in the code doing just enough to get their feature working).

   Sam

Index: ifclone.c
===================================================================
RCS file: /usr/ncvs/src/sbin/ifconfig/ifclone.c,v
retrieving revision 1.3
diff -u -r1.3 ifclone.c
--- ifclone.c   12 Aug 2006 18:07:17 -0000      1.3
+++ ifclone.c   30 Mar 2008 19:58:35 -0000
@@ -143,9 +143,9 @@
 }
 
 static struct cmd clone_cmds[] = {
-       DEF_CMD("create",       0,      clone_create),
+       DEF_CLONE_CMD("create", 0,      clone_create),
        DEF_CMD("destroy",      0,      clone_destroy),
-       DEF_CMD("plumb",        0,      clone_create),
+       DEF_CLONE_CMD("plumb",  0,      clone_create),
        DEF_CMD("unplumb",      0,      clone_destroy),
 };
 
Index: ifconfig.c
===================================================================
RCS file: /usr/ncvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.135
diff -u -r1.135 ifconfig.c
--- ifconfig.c  10 Dec 2007 02:31:00 -0000      1.135
+++ ifconfig.c  30 Mar 2008 19:43:34 -0000
@@ -93,7 +93,8 @@
 int    supmedia = 0;
 int    printkeys = 0;          /* Print keying material for interfaces. */
 
-static int ifconfig(int argc, char *const *argv, const struct afswtch *afp);
+static int ifconfig(int argc, char *const *argv, int iscreate,
+               const struct afswtch *afp);
 static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
                struct ifaddrs *ifa);
 static void tunnel_status(int s);
@@ -247,7 +248,7 @@
                                if (iflen >= sizeof(name))
                                        errx(1, "%s: cloning name too long",
                                            ifname);
-                               ifconfig(argc, argv, NULL);
+                               ifconfig(argc, argv, 1, NULL);
                                exit(0);
                        }
                        errx(1, "interface %s does not exist", ifname);
@@ -305,7 +306,7 @@
                }
 
                if (argc > 0)
-                       ifconfig(argc, argv, afp);
+                       ifconfig(argc, argv, 0, afp);
                else
                        status(afp, sdl, ifa);
        }
@@ -433,17 +434,19 @@
        DEF_CMD("ifdstaddr", 0, setifdstaddr);
 
 static int
-ifconfig(int argc, char *const *argv, const struct afswtch *afp)
+ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *afp)
 {
+       const struct afswtch *nafp;
        struct callback *cb;
        int s;
 
+       strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+top:
        if (afp == NULL)
                afp = af_getbyname("inet");
        ifr.ifr_addr.sa_family =
                afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ?
                AF_INET : afp->af_af;
-       strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
 
        if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
                err(1, "socket(family %u,SOCK_DGRAM", ifr.ifr_addr.sa_family);
@@ -460,6 +463,33 @@
                        p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd);
                }
                if (p->c_u.c_func || p->c_u.c_func2) {
+                       if (iscreate && !p->c_iscloneop) { 
+                               /*
+                                * Push the clone create callback so the new
+                                * device is created and can be used for any
+                                * remaining arguments.
+                                */
+                               cb = callbacks;
+                               if (cb == NULL)
+                                       errx(1, "internal error, no callback");
+                               callbacks = cb->cb_next;
+                               cb->cb_func(s, cb->cb_arg);
+                               iscreate = 0;
+                               /*
+                                * Handle any address family spec that
+                                * immediately follows and potentially
+                                * recreate the socket.
+                                */
+                               nafp = af_getbyname(*argv);
+                               if (nafp != NULL) {
+                                       argc--, argv++;
+                                       if (nafp != afp) {
+                                               close(s);
+                                               afp = nafp;
+                                               goto top;
+                                       }
+                               }
+                       }
                        if (p->c_parameter == NEXTARG) {
                                if (argv[1] == NULL)
                                        errx(1, "'%s' requires argument",
Index: ifconfig.h
===================================================================
RCS file: /usr/ncvs/src/sbin/ifconfig/ifconfig.h,v
retrieving revision 1.21
diff -u -r1.21 ifconfig.h
--- ifconfig.h  13 Jun 2007 18:07:59 -0000      1.21
+++ ifconfig.h  30 Mar 2008 19:38:31 -0000
@@ -52,6 +52,7 @@
                c_func  *c_func;
                c_func2 *c_func2;
        } c_u;
+       int     c_iscloneop;
        struct cmd *c_next;
 };
 void   cmd_register(struct cmd *);
@@ -71,6 +72,8 @@
 #define        DEF_CMD_ARG(name, func)         { name, NEXTARG, { .c_func = 
func } }
 #define        DEF_CMD_OPTARG(name, func)      { name, OPTARG, { .c_func = 
func } }
 #define        DEF_CMD_ARG2(name, func)        { name, NEXTARG2, { .c_func2 = 
func } }
+#define        DEF_CLONE_CMD(name, param, func) { name, param, { .c_func = 
func }, 1 }
+#define        DEF_CLONE_CMD_ARG(name, func)   { name, NEXTARG, { .c_func = 
func }, 1 }
 
 struct ifaddrs;
 struct addrinfo;
Index: ifvlan.c
===================================================================
RCS file: /usr/ncvs/src/sbin/ifconfig/ifvlan.c,v
retrieving revision 1.12
diff -u -r1.12 ifvlan.c
--- ifvlan.c    9 Jul 2006 06:10:23 -0000       1.12
+++ ifvlan.c    30 Mar 2008 19:25:26 -0000
@@ -172,8 +172,8 @@
 }
 
 static struct cmd vlan_cmds[] = {
-       DEF_CMD_ARG("vlan",                             setvlantag),
-       DEF_CMD_ARG("vlandev",                          setvlandev),
+       DEF_CLONE_CMD_ARG("vlan",                       setvlantag),
+       DEF_CLONE_CMD_ARG("vlandev",                    setvlandev),
        /* XXX For compatibility.  Should become DEF_CMD() some day. */
        DEF_CMD_OPTARG("-vlandev",                      unsetvlandev),
        DEF_CMD("vlanmtu",      IFCAP_VLAN_MTU,         setifcap),
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to