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
This commit is contained in:
parent
836d250db3
commit
2fa02c5fb7
@ -143,9 +143,9 @@ DECL_CMD_FUNC(clone_destroy, arg, d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct cmd clone_cmds[] = {
|
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("destroy", 0, clone_destroy),
|
||||||
DEF_CMD("plumb", 0, clone_create),
|
DEF_CLONE_CMD("plumb", 0, clone_create),
|
||||||
DEF_CMD("unplumb", 0, clone_destroy),
|
DEF_CMD("unplumb", 0, clone_destroy),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +93,8 @@ int noload;
|
|||||||
int supmedia = 0;
|
int supmedia = 0;
|
||||||
int printkeys = 0; /* Print keying material for interfaces. */
|
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,
|
static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
|
||||||
struct ifaddrs *ifa);
|
struct ifaddrs *ifa);
|
||||||
static void tunnel_status(int s);
|
static void tunnel_status(int s);
|
||||||
@ -247,7 +248,7 @@ main(int argc, char *argv[])
|
|||||||
if (iflen >= sizeof(name))
|
if (iflen >= sizeof(name))
|
||||||
errx(1, "%s: cloning name too long",
|
errx(1, "%s: cloning name too long",
|
||||||
ifname);
|
ifname);
|
||||||
ifconfig(argc, argv, NULL);
|
ifconfig(argc, argv, 1, NULL);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
errx(1, "interface %s does not exist", ifname);
|
errx(1, "interface %s does not exist", ifname);
|
||||||
@ -305,7 +306,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 0)
|
if (argc > 0)
|
||||||
ifconfig(argc, argv, afp);
|
ifconfig(argc, argv, 0, afp);
|
||||||
else
|
else
|
||||||
status(afp, sdl, ifa);
|
status(afp, sdl, ifa);
|
||||||
}
|
}
|
||||||
@ -433,17 +434,19 @@ static const struct cmd setifdstaddr_cmd =
|
|||||||
DEF_CMD("ifdstaddr", 0, setifdstaddr);
|
DEF_CMD("ifdstaddr", 0, setifdstaddr);
|
||||||
|
|
||||||
static int
|
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;
|
struct callback *cb;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
|
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
|
||||||
|
top:
|
||||||
if (afp == NULL)
|
if (afp == NULL)
|
||||||
afp = af_getbyname("inet");
|
afp = af_getbyname("inet");
|
||||||
ifr.ifr_addr.sa_family =
|
ifr.ifr_addr.sa_family =
|
||||||
afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ?
|
afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ?
|
||||||
AF_INET : afp->af_af;
|
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)
|
if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
|
||||||
err(1, "socket(family %u,SOCK_DGRAM", ifr.ifr_addr.sa_family);
|
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);
|
p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd);
|
||||||
}
|
}
|
||||||
if (p->c_u.c_func || p->c_u.c_func2) {
|
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 (p->c_parameter == NEXTARG) {
|
||||||
if (argv[1] == NULL)
|
if (argv[1] == NULL)
|
||||||
errx(1, "'%s' requires argument",
|
errx(1, "'%s' requires argument",
|
||||||
|
@ -52,6 +52,7 @@ struct cmd {
|
|||||||
c_func *c_func;
|
c_func *c_func;
|
||||||
c_func2 *c_func2;
|
c_func2 *c_func2;
|
||||||
} c_u;
|
} c_u;
|
||||||
|
int c_iscloneop;
|
||||||
struct cmd *c_next;
|
struct cmd *c_next;
|
||||||
};
|
};
|
||||||
void cmd_register(struct cmd *);
|
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_ARG(name, func) { name, NEXTARG, { .c_func = func } }
|
||||||
#define DEF_CMD_OPTARG(name, func) { name, OPTARG, { .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_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 ifaddrs;
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
|
@ -172,8 +172,8 @@ DECL_CMD_FUNC(unsetvlandev, val, d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct cmd vlan_cmds[] = {
|
static struct cmd vlan_cmds[] = {
|
||||||
DEF_CMD_ARG("vlan", setvlantag),
|
DEF_CLONE_CMD_ARG("vlan", setvlantag),
|
||||||
DEF_CMD_ARG("vlandev", setvlandev),
|
DEF_CLONE_CMD_ARG("vlandev", setvlandev),
|
||||||
/* XXX For compatibility. Should become DEF_CMD() some day. */
|
/* XXX For compatibility. Should become DEF_CMD() some day. */
|
||||||
DEF_CMD_OPTARG("-vlandev", unsetvlandev),
|
DEF_CMD_OPTARG("-vlandev", unsetvlandev),
|
||||||
DEF_CMD("vlanmtu", IFCAP_VLAN_MTU, setifcap),
|
DEF_CMD("vlanmtu", IFCAP_VLAN_MTU, setifcap),
|
||||||
|
Loading…
Reference in New Issue
Block a user