diff options
author | sam <sam@FreeBSD.org> | 2008-03-31 15:38:07 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2008-03-31 15:38:07 +0000 |
commit | 1cec369535292eab06c22690afab8043336f2e23 (patch) | |
tree | 652d2393cae1d93b05ca165ce9b50c9062f9eeeb /sbin/ifconfig | |
parent | 206a6eb6a9859d0eefd10a748c7910492ce7b058 (diff) | |
download | FreeBSD-src-1cec369535292eab06c22690afab8043336f2e23.zip FreeBSD-src-1cec369535292eab06c22690afab8043336f2e23.tar.gz |
Fix handling of create operation together with setting other parameters:
o mark cmds/parameters to indicate they are potential arguments to a clone
operation (e.g. vlantag)
o when handling a create/clone operation do the callback on seeing the first
non-clone cmd line argument so the new device is created and can be used;
and re-setup operating state to reflect the newly created device
Reviewed by: Eugene Grosbein
MFC after: 2 weeks
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r-- | sbin/ifconfig/ifclone.c | 4 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 40 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.h | 3 | ||||
-rw-r--r-- | sbin/ifconfig/ifvlan.c | 4 |
4 files changed, 42 insertions, 9 deletions
diff --git a/sbin/ifconfig/ifclone.c b/sbin/ifconfig/ifclone.c index 3fda062..bf68d56 100644 --- a/sbin/ifconfig/ifclone.c +++ b/sbin/ifconfig/ifclone.c @@ -143,9 +143,9 @@ DECL_CMD_FUNC(clone_destroy, arg, d) } 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), }; diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 3676396..4819679 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -93,7 +93,8 @@ int noload; 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 @@ main(int argc, char *argv[]) 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 @@ main(int argc, char *argv[]) } if (argc > 0) - ifconfig(argc, argv, afp); + ifconfig(argc, argv, 0, afp); else status(afp, sdl, ifa); } @@ -433,17 +434,19 @@ static const struct cmd setifdstaddr_cmd = 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 @@ ifconfig(int argc, char *const *argv, const struct afswtch *afp) 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", diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index 5ef36c9..70c1cad 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -52,6 +52,7 @@ struct cmd { 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 @@ void callback_register(callback_func *, void *); #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; diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c index 205ed21..89bc9af 100644 --- a/sbin/ifconfig/ifvlan.c +++ b/sbin/ifconfig/ifvlan.c @@ -172,8 +172,8 @@ DECL_CMD_FUNC(unsetvlandev, val, d) } 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), |