diff options
author | sam <sam@FreeBSD.org> | 2006-07-09 06:04:01 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2006-07-09 06:04:01 +0000 |
commit | 2350e920372288f7ed8401d362497880b30dea50 (patch) | |
tree | 9d7fca708f49f055d33f7ea0b8387e3b17763e09 /sys/net/if_vlan.c | |
parent | d4c884886f5a791f00d676a628a847df63fd2f4d (diff) | |
download | FreeBSD-src-2350e920372288f7ed8401d362497880b30dea50.zip FreeBSD-src-2350e920372288f7ed8401d362497880b30dea50.tar.gz |
Revise network interface cloning to take an optional opaque
parameter that can specify configuration parameters:
o rev cloner api's to add optional parameter block
o add SIOCCREATE2 that accepts parameter data
o rev vlan support to use new api (maintain old code)
Reviewed by: arch@
Diffstat (limited to 'sys/net/if_vlan.c')
-rw-r--r-- | sys/net/if_vlan.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 0ad90ca..34ef7ee 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -192,7 +192,7 @@ static void vlan_trunk_capabilities(struct ifnet *ifp); 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 *); static void vlan_ifdetach(void *arg, struct ifnet *ifp); @@ -615,7 +615,7 @@ vlan_clone_match(struct if_clone *ifc, const char *name) } 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; @@ -626,9 +626,39 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len) struct ifvlan *ifv; struct ifnet *ifp; struct ifnet *p; + struct vlanreq vlr; static const u_char eaddr[6]; /* 00:00:00:00:00:00 */ - 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); + + ethertag = 1; + tag = vlr.vlr_tag; + wildcard = (unit < 0); + } else if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) { ethertag = 1; unit = -1; wildcard = 0; |