From owner-p4-projects@FreeBSD.ORG Mon Feb 7 17:40:50 2005 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6562B16A4D0; Mon, 7 Feb 2005 17:40:50 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2104E16A4CE for ; Mon, 7 Feb 2005 17:40:50 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id C978B43D5C for ; Mon, 7 Feb 2005 17:40:49 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j17HenD9028224 for ; Mon, 7 Feb 2005 17:40:49 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j17Henbj028221 for perforce@freebsd.org; Mon, 7 Feb 2005 17:40:49 GMT (envelope-from sam@freebsd.org) Date: Mon, 7 Feb 2005 17:40:49 GMT Message-Id: <200502071740.j17Henbj028221@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 70523 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Feb 2005 17:40:51 -0000 http://perforce.freebsd.org/chv.cgi?CH=70523 Change 70523 by sam@sam_ebb on 2005/02/07 17:40:26 revise cloning support to take an optional device-specific parameter block Affected files ... .. //depot/projects/vap/sys/net/if.c#2 edit .. //depot/projects/vap/sys/net/if_clone.c#2 edit .. //depot/projects/vap/sys/net/if_clone.h#2 edit .. //depot/projects/vap/sys/net/if_disc.c#2 edit .. //depot/projects/vap/sys/net/if_faith.c#2 edit .. //depot/projects/vap/sys/net/if_gif.c#2 edit .. //depot/projects/vap/sys/net/if_gre.c#2 edit .. //depot/projects/vap/sys/net/if_loop.c#2 edit .. //depot/projects/vap/sys/net/if_ppp.c#2 edit .. //depot/projects/vap/sys/net/if_stf.c#2 edit .. //depot/projects/vap/sys/net/if_vlan.c#2 edit .. //depot/projects/wifi/sbin/ifconfig/ifclone.c#6 edit .. //depot/projects/wifi/sbin/ifconfig/ifconfig.c#11 edit .. //depot/projects/wifi/sbin/ifconfig/ifconfig.h#9 edit .. //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#37 edit .. //depot/projects/wifi/sbin/ifconfig/ifvlan.c#8 edit Differences ... ==== //depot/projects/vap/sys/net/if.c#2 (text+ko) ==== @@ -1381,7 +1381,7 @@ if ((error = suser(td)) != 0) return (error); return ((cmd == SIOCIFCREATE) ? - if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) : + if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name), ifr->ifr_data) : if_clone_destroy(ifr->ifr_name)); case SIOCIFGCLONERS: ==== //depot/projects/vap/sys/net/if_clone.c#2 (text+ko) ==== @@ -112,7 +112,7 @@ * Create a clone network interface. */ int -if_clone_create(char *name, size_t len) +if_clone_create(char *name, size_t len, caddr_t params) { int err; struct if_clone *ifc; @@ -133,7 +133,7 @@ if (ifc == NULL) return (EINVAL); - err = (*ifc->ifc_create)(ifc, name, len); + err = (*ifc->ifc_create)(ifc, name, len, params); IF_CLONE_REMREF(ifc); return (err); } @@ -396,7 +396,7 @@ for (unit = 0; unit < ifcs->ifcs_minifs; unit++) { snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); - err = (*ifc->ifc_create)(ifc, name, IFNAMSIZ); + err = (*ifc->ifc_create)(ifc, name, IFNAMSIZ, (caddr_t) 0); KASSERT(err == 0, ("%s: failed to create required interface %s", __func__, name)); @@ -425,7 +425,7 @@ } int -ifc_simple_create(struct if_clone *ifc, char *name, size_t len) +ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) { char *dp; int wildcard; @@ -443,7 +443,7 @@ if (err != 0) return (err); - err = ifcs->ifcs_create(ifc, unit); + err = ifcs->ifcs_create(ifc, unit, params); if (err != 0) { ifc_free_unit(ifc, unit); return (err); ==== //depot/projects/vap/sys/net/if_clone.h#2 (text+ko) ==== @@ -61,7 +61,7 @@ /* (c) Driver specific cloning functions. Called with no locks held. */ void (*ifc_attach)(struct if_clone *); int (*ifc_match)(struct if_clone *, const char *); - int (*ifc_create)(struct if_clone *, char *, size_t); + int (*ifc_create)(struct if_clone *, char *, size_t, caddr_t); int (*ifc_destroy)(struct if_clone *, struct ifnet *); long ifc_refcnt; /* (i) Refrence count. */ @@ -72,7 +72,7 @@ void if_clone_attach(struct if_clone *); void if_clone_detach(struct if_clone *); -int if_clone_create(char *, size_t); +int if_clone_create(char *, size_t, caddr_t); int if_clone_destroy(const char *); int if_clone_list(struct if_clonereq *); @@ -88,7 +88,7 @@ struct ifc_simple_data { int ifcs_minifs; /* minimum number of interfaces */ - int (*ifcs_create)(struct if_clone *, int); + int (*ifcs_create)(struct if_clone *, int, caddr_t); void (*ifcs_destroy)(struct ifnet *); }; @@ -105,7 +105,7 @@ void ifc_simple_attach(struct if_clone *); int ifc_simple_match(struct if_clone *, const char *); -int ifc_simple_create(struct if_clone *, char *, size_t); +int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t); int ifc_simple_destroy(struct if_clone *, struct ifnet *); #endif /* _KERNEL */ ==== //depot/projects/vap/sys/net/if_disc.c#2 (text+ko) ==== @@ -70,7 +70,7 @@ struct sockaddr *, struct rtentry *); static void discrtrequest(int, struct rtentry *, struct rt_addrinfo *); static int discioctl(struct ifnet *, u_long, caddr_t); -static int disc_clone_create(struct if_clone *, int); +static int disc_clone_create(struct if_clone *, int, caddr_t); static void disc_clone_destroy(struct ifnet *); static struct mtx disc_mtx; @@ -80,7 +80,7 @@ IFC_SIMPLE_DECLARE(disc, 0); static int -disc_clone_create(struct if_clone *ifc, int unit) +disc_clone_create(struct if_clone *ifc, int unit, caddr_t params) { struct ifnet *ifp; struct disc_softc *sc; ==== //depot/projects/vap/sys/net/if_faith.c#2 (text+ko) ==== @@ -101,7 +101,7 @@ static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface"); static LIST_HEAD(, faith_softc) faith_softc_list; -static int faith_clone_create(struct if_clone *, int); +static int faith_clone_create(struct if_clone *, int, caddr_t); static void faith_clone_destroy(struct ifnet *); static void faith_destroy(struct faith_softc *); @@ -161,9 +161,10 @@ MODULE_VERSION(if_faith, 1); static int -faith_clone_create(ifc, unit) +faith_clone_create(ifc, unit, params) struct if_clone *ifc; int unit; + caddr_t params; { struct faith_softc *sc; ==== //depot/projects/vap/sys/net/if_gif.c#2 (text+ko) ==== @@ -98,7 +98,7 @@ void (*ng_gif_attach_p)(struct ifnet *ifp); void (*ng_gif_detach_p)(struct ifnet *ifp); -static int gif_clone_create(struct if_clone *, int); +static int gif_clone_create(struct if_clone *, int, caddr_t); static void gif_clone_destroy(struct ifnet *); IFC_SIMPLE_DECLARE(gif, 0); @@ -137,9 +137,10 @@ ¶llel_tunnels, 0, "Allow parallel tunnels?"); static int -gif_clone_create(ifc, unit) +gif_clone_create(ifc, unit, params) struct if_clone *ifc; int unit; + caddr_t params; { struct gif_softc *sc; ==== //depot/projects/vap/sys/net/if_gre.c#2 (text+ko) ==== @@ -102,7 +102,7 @@ struct gre_softc_head gre_softc_list; -static int gre_clone_create(struct if_clone *, int); +static int gre_clone_create(struct if_clone *, int, caddr_t); static void gre_clone_destroy(struct ifnet *); static int gre_ioctl(struct ifnet *, u_long, caddr_t); static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *, @@ -161,9 +161,10 @@ } static int -gre_clone_create(ifc, unit) +gre_clone_create(ifc, unit, params) struct if_clone *ifc; int unit; + caddr_t params; { struct gre_softc *sc; ==== //depot/projects/vap/sys/net/if_loop.c#2 (text+ko) ==== @@ -101,7 +101,7 @@ static void lortrequest(int, struct rtentry *, struct rt_addrinfo *); int looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt); -static int lo_clone_create(struct if_clone *, int); +static int lo_clone_create(struct if_clone *, int, caddr_t); static void lo_clone_destroy(struct ifnet *); struct ifnet *loif = NULL; /* Used externally */ @@ -133,9 +133,10 @@ } static int -lo_clone_create(ifc, unit) +lo_clone_create(ifc, unit, params) struct if_clone *ifc; int unit; + caddr_t params; { struct lo_softc *sc; ==== //depot/projects/vap/sys/net/if_ppp.c#2 (text+ko) ==== @@ -157,7 +157,7 @@ static void ppp_ccp_closed(struct ppp_softc *); static void ppp_inproc(struct ppp_softc *, struct mbuf *); static void pppdumpm(struct mbuf *m0); -static int ppp_clone_create(struct if_clone *, int); +static int ppp_clone_create(struct if_clone *, int, caddr_t); static void ppp_clone_destroy(struct ifnet *); struct ppp_softc * @@ -221,7 +221,7 @@ #endif /* PPP_COMPRESS */ static int -ppp_clone_create(struct if_clone *ifc, int unit) +ppp_clone_create(struct if_clone *ifc, int unit, caddr_t params) { struct ppp_softc *sc; @@ -354,7 +354,7 @@ /* Try to clone an interface if we don't have a free one */ if (sc == NULL) { strcpy(tmpname, PPPNAME); - if (if_clone_create(tmpname, sizeof(tmpname)) != 0) + if (if_clone_create(tmpname, sizeof(tmpname), (caddr_t) 0) != 0) return NULL; ifp = ifunit(tmpname); if (ifp == NULL) ==== //depot/projects/vap/sys/net/if_stf.c#2 (text+ko) ==== @@ -178,7 +178,7 @@ static int stf_ioctl(struct ifnet *, u_long, caddr_t); static int stf_clone_match(struct if_clone *, const char *); -static int stf_clone_create(struct if_clone *, char *, size_t); +static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t); static int stf_clone_destroy(struct if_clone *, struct ifnet *); struct if_clone stf_cloner = IFC_CLONE_INITIALIZER(STFNAME, NULL, 0, NULL, stf_clone_match, stf_clone_create, stf_clone_destroy); @@ -197,7 +197,7 @@ } static int -stf_clone_create(struct if_clone *ifc, char *name, size_t len) +stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) { int err, unit; struct stf_softc *sc; ==== //depot/projects/vap/sys/net/if_vlan.c#2 (text+ko) ==== @@ -131,7 +131,7 @@ static struct ifnet *vlan_clone_match_ethertag(struct if_clone *, const char *, int *); static int vlan_clone_match(struct if_clone *, const char *); -static int vlan_clone_create(struct if_clone *, char *, size_t); +static int vlan_clone_create(struct if_clone *, char *, size_t, caddr_t); static int vlan_clone_destroy(struct if_clone *, struct ifnet *); struct if_clone vlan_cloner = IFC_CLONE_INITIALIZER(VLANNAME, NULL, IF_MAXUNIT, @@ -313,7 +313,7 @@ } static int -vlan_clone_create(struct if_clone *ifc, char *name, size_t len) +vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) { char *dp; int wildcard; @@ -324,8 +324,37 @@ struct ifvlan *ifv; struct ifnet *ifp; struct ifnet *p; + struct vlanreq vlr; - if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) { + /* + * There are 3 (ugh) ways to specify the cloned device: + * o pass a parameter block with the clone request. + * o specify parameters in the text of the clone device name + * o specify no parameters and get an unattached device that + * must be configured separately. + * The first technique is preferred; the latter two are + * supported for backwards compatibilty. + */ + if (params) { + error = copyin(params, &vlr, sizeof(vlr)); + if (error) + return error; + p = ifunit(vlr.vlr_parent); + if (p == NULL) + return ENXIO; + /* + * Don't let the caller set up a VLAN tag with + * anything except VLID bits. + */ + if (vlr.vlr_tag & ~EVL_VLID_MASK) + return (EINVAL); + error = ifc_name2unit(name, &unit); + if (error != 0) + return (error); + + tag = vlr.vlr_tag; + wildcard = (unit < 0); + } else if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) { ethertag = 1; unit = -1; wildcard = 0; ==== //depot/projects/wifi/sbin/ifconfig/ifclone.c#6 (text+ko) ==== @@ -88,48 +88,62 @@ free(buf); } +static clone_callback_func *clone_cb = NULL; + void -clone_create(void) +clone_setcallback(clone_callback_func *p) { - int s; + if (clone_cb != NULL && clone_cb != p) + errx(1, "conflicting device create parameters"); + clone_cb = p; +} - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s == -1) - err(1, "socket(AF_INET,SOCK_DGRAM)"); +/* + * Do the actual clone operation. Any parameters must have been + * setup by now. If a callback has been setup to do the work + * then defer to it; otherwise do a simple create operation with + * no parameters. + */ +static void +ifclonecreate(int s, void *arg) +{ + struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); (void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCIFCREATE, &ifr) < 0) - err(1, "SIOCIFCREATE"); + if (clone_cb == NULL) { + /* NB: no parameters */ + if (ioctl(s, SIOCIFCREATE, &ifr) < 0) + err(1, "SIOCIFCREATE"); + } else { + clone_cb(s, &ifr); + } /* - * If we get a different name back then we put in, we probably - * want to print it out, but we might change our mind later so - * we just signal our intrest and leave the printout for later. + * If we get a different name back than we put in, print it. */ - if (strcmp(name, ifr.ifr_name) != 0) { - printname = 1; + if (strncmp(name, ifr.ifr_name, sizeof(name)) != 0) { strlcpy(name, ifr.ifr_name, sizeof(name)); + printf("%s\n", name); } +} - close(s); +static +DECL_CMD_FUNC(clone_create, arg, d) +{ + callback_register(ifclonecreate, NULL); } -static void -clone_destroy(const char *val, int d, int s, const struct afswtch *rafp) +static +DECL_CMD_FUNC(clone_destroy, arg, d) { - (void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) err(1, "SIOCIFDESTROY"); - /* - * If we create and destroy an interface in the same command, - * there isn't any reason to print it's name. - */ - printname = 0; } static struct cmd clone_cmds[] = { + DEF_CMD("create", 0, clone_create), DEF_CMD("destroy", 0, clone_destroy), DEF_CMD("unplumb", 0, clone_destroy), }; ==== //depot/projects/wifi/sbin/ifconfig/ifconfig.c#11 (text+ko) ==== @@ -91,7 +91,6 @@ int verbose; int supmedia = 0; -int printname = 0; /* Print the name of the created interface. */ static int ifconfig(int argc, char *const *argv, const struct afswtch *afp); static void status(const struct afswtch *afp, int addrcount, @@ -233,16 +232,14 @@ ifindex = if_nametoindex(name); if (ifindex == 0) { /* - * NOTE: We must special-case the `create' command right - * here as we would otherwise fail when trying to find - * the interface. + * NOTE: We must special-case the `create' command + * right here as we would otherwise fail when trying + * to find the interface. */ if (argc > 0 && (strcmp(argv[0], "create") == 0 || strcmp(argv[0], "plumb") == 0)) { - clone_create(); - argc--, argv++; - if (argc == 0) - goto end; + ifconfig(argc, argv, NULL); + exit(0); } errx(1, "interface %s does not exist", name); } @@ -353,9 +350,6 @@ if (namesonly && need_nl > 0) putchar('\n'); -end: - if (printname) - printf("%s\n", name); exit (0); } @@ -780,12 +774,6 @@ } strlcpy(name, newname, sizeof(name)); free(newname); - - /* - * Even if we just created the interface, we don't need to print - * its name because we just nailed it down separately. - */ - printname = 0; } /* ==== //depot/projects/wifi/sbin/ifconfig/ifconfig.h#9 (text+ko) ==== @@ -126,7 +126,6 @@ extern char name[IFNAMSIZ]; /* name of interface */ extern int allmedia; extern int supmedia; -extern int printname; extern int flags; extern int newaddr; extern int verbose; @@ -139,4 +138,5 @@ void ifmaybeload(char *name); -void clone_create(void); +typedef void clone_callback_func(int, struct ifreq *); +void clone_setcallback(clone_callback_func *); ==== //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#37 (text+ko) ==== @@ -1120,56 +1120,49 @@ #undef iseq } +static struct ieee80211_clone_params params = { + .icp_opmode = IEEE80211_M_STA, /* default to station mode */ +}; + +static void +wlan_create(int s, struct ifreq *ifr) +{ + if (params.icp_parent[0] == '\0') + errx(1, "must specify a parent when creating a wlan device"); + ifr->ifr_data = (caddr_t) ¶ms; + if (ioctl(s, SIOCIFCREATE, ifr) < 0) + err(1, "SIOCIFCREATE"); +} + static -DECL_CMD_FUNC(set80211create, arg, d) +DECL_CMD_FUNC(set80211wlandev, arg, d) +{ + strlcpy(params.icp_parent, arg, IFNAMSIZ); + clone_setcallback(wlan_create); +} + +static +DECL_CMD_FUNC(set80211wlantype, arg, d) { #define iseq(a,b) (strncasecmp(a,b,sizeof(b)-1) == 0) - struct ifreq ifr; - int opmode; - if (iseq(arg, "sta")) - opmode = IEEE80211_M_STA; + params.icp_opmode = IEEE80211_M_STA; else if (iseq(arg, "ahdemo") || iseq(arg, "adhoc-demo")) - opmode = IEEE80211_M_AHDEMO; + params.icp_opmode = IEEE80211_M_AHDEMO; else if (iseq(arg, "ibss") || iseq(arg, "adhoc")) - opmode = IEEE80211_M_IBSS; + params.icp_opmode = IEEE80211_M_IBSS; else if (iseq(arg, "ap") || iseq(arg, "hostap")) - opmode = IEEE80211_M_HOSTAP; + params.icp_opmode = IEEE80211_M_HOSTAP; else if (iseq(arg, "wds")) - opmode = IEEE80211_M_WDS; + params.icp_opmode = IEEE80211_M_WDS; else if (iseq(arg, "monitor")) - opmode = IEEE80211_M_MONITOR; + params.icp_opmode = IEEE80211_M_MONITOR; else errx(1, "Don't know how to create %s for %s", arg, name); - - (void) memset(&ifr, 0, sizeof(ifr)); - (void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - ifr.ifr_flags = opmode; - if (ioctl(s, SIOC80211IFCREATE, &ifr) < 0) - err(1, "SIOC80211IFCREATE"); - /* - * If we get a different name back then we put in, we probably - * want to print it out, but we might change our mind later so - * we just signal our interest and leave the printout for later. - */ - if (strcmp(name, ifr.ifr_name) != 0) { - printname = 1; - strlcpy(name, ifr.ifr_name, sizeof(name)); - } + clone_setcallback(wlan_create); #undef iseq } -static -DECL_CMD_FUNC(set80211destroy, arg, d) -{ - struct ifreq req; - - (void) memset(&req, 0, sizeof(req)); - (void) strncpy(req.ifr_name, name, sizeof(req.ifr_name)); - if (ioctl(s, SIOC80211IFDESTROY, &req) < 0) - err(1, "SIOC80211IFDESTROY"); -} - static enum ieee80211_opmode get80211opmode(int s) { @@ -1870,8 +1863,8 @@ DEF_CMD("-ff", 0, set80211fastframes), DEF_CMD("turbo", 1, set80211turbo), DEF_CMD("-turbo", 0, set80211turbo), - DEF_CMD_ARG("create", set80211create), - DEF_CMD("kill", 0, set80211destroy), /*XXX*/ + DEF_CMD_ARG("wlandev", set80211wlandev), + DEF_CMD_ARG("wlantype", set80211wlantype), }; static struct afswtch af_ieee80211 = { .af_name = "af_ieee80211", ==== //depot/projects/wifi/sbin/ifconfig/ifvlan.c#8 (text+ko) ==== @@ -58,8 +58,12 @@ static const char rcsid[] = "$FreeBSD: src/sbin/ifconfig/ifvlan.c,v 1.7 2004/12/31 19:46:27 sam Exp $"; #endif -static int __tag = 0; -static int __have_tag = 0; + +#define NOTAG ((u_short) -1) + +static struct vlanreq params = { + .vlr_tag = NOTAG, +}; static void vlan_status(int s) @@ -75,58 +79,66 @@ printf("\tvlan: %d parent interface: %s\n", vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ? "" : vreq.vlr_parent); +} - return; +static void +vlan_create(int s, struct ifreq *ifr) +{ + if (params.vlr_tag != NOTAG || params.vlr_parent[0] != '\0') { + /* + * One or both parameters were specified, make sure both. + */ + if (params.vlr_tag == NOTAG) + errx(1, "must specify a tag for vlan create"); + if (params.vlr_parent[0] == '\0') + errx(1, "must specify a parent device for vlan create"); + ifr->ifr_data = (caddr_t) ¶ms; + } + if (ioctl(s, SIOCIFCREATE, ifr) < 0) + err(1, "SIOCIFCREATE"); } -static void -setvlantag(const char *val, int d, int s, const struct afswtch *afp) +static +DECL_CMD_FUNC(setvlantag, val, d) { u_int16_t tag; struct vlanreq vreq; - __tag = tag = atoi(val); - __have_tag = 1; + tag = (u_int16_t) atoi(val); bzero((char *)&vreq, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&vreq; - if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) - err(1, "SIOCGETVLAN"); - - vreq.vlr_tag = tag; - - if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) - err(1, "SIOCSETVLAN"); - - return; + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) != -1) { + vreq.vlr_tag = tag; + if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) + err(1, "SIOCSETVLAN"); + } else { + params.vlr_tag = tag; + clone_setcallback(vlan_create); + } } -static void -setvlandev(const char *val, int d, int s, const struct afswtch *afp) +static +DECL_CMD_FUNC(setvlandev, val, d) { struct vlanreq vreq; - if (!__have_tag) - errx(1, "must specify both vlan tag and device"); - bzero((char *)&vreq, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&vreq; - if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) - err(1, "SIOCGETVLAN"); - - strncpy(vreq.vlr_parent, val, sizeof(vreq.vlr_parent)); - vreq.vlr_tag = __tag; - - if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) - err(1, "SIOCSETVLAN"); - - return; + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) != -1) { + strncpy(vreq.vlr_parent, val, sizeof(vreq.vlr_parent)); + if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) + err(1, "SIOCSETVLAN"); + } else { + strlcpy(params.vlr_parent, val, sizeof(params.vlr_parent)); + clone_setcallback(vlan_create); + } } -static void -unsetvlandev(const char *val, int d, int s, const struct afswtch *afp) +static +DECL_CMD_FUNC(unsetvlandev, val, d) { struct vlanreq vreq; @@ -141,8 +153,6 @@ if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) err(1, "SIOCSETVLAN"); - - return; } static struct cmd vlan_cmds[] = {