Page MenuHomeFreeBSD

D27505.id82886.diff
No OneTemporary

D27505.id82886.diff

Index: sys/net/if_clone.c
===================================================================
--- sys/net/if_clone.c
+++ sys/net/if_clone.c
@@ -571,7 +571,7 @@
/*
* A utility function to extract unit numbers from interface names of
- * the form name###[.###].
+ * the form name###.
*
* Returns 0 on success and an error on failure.
*/
@@ -582,9 +582,7 @@
int cutoff = INT_MAX / 10;
int cutlim = INT_MAX % 10;
- if ((cp = strrchr(name, '.')) == NULL)
- cp = name;
- for (; *cp != '\0' && (*cp < '0' || *cp > '9'); cp++);
+ for (cp = name; *cp != '\0' && (*cp < '0' || *cp > '9'); cp++);
if (*cp == '\0') {
*unit = -1;
} else if (cp[0] == '0' && cp[1] != '\0') {
Index: sys/net/if_vlan.c
===================================================================
--- sys/net/if_vlan.c
+++ sys/net/if_vlan.c
@@ -977,63 +977,79 @@
vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
char *dp;
- int wildcard;
+ bool wildcard;
+ bool subinterface = false;
int unit;
int error;
- int vid;
- uint16_t proto;
+ int vid = 0;
+ uint16_t proto = ETHERTYPE_VLAN;
struct ifvlan *ifv;
struct ifnet *ifp;
- struct ifnet *p;
+ struct ifnet *p = NULL;
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
struct vlanreq vlr;
static const u_char eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
- proto = ETHERTYPE_VLAN;
/*
- * There are two ways to specify the cloned device:
+ * There are three 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 is supported
+ * The first technique is preferred; the latter two are supported
* for backwards compatibility.
*
* XXXRW: Note historic use of the word "tag" here. New ioctls may be
* called for.
*/
+
if (params) {
error = copyin(params, &vlr, sizeof(vlr));
if (error)
return error;
+ vid = vlr.vlr_tag;
+ proto = vlr.vlr_proto;
+
p = ifunit_ref(vlr.vlr_parent);
if (p == NULL)
return (ENXIO);
- error = ifc_name2unit(name, &unit);
- if (error != 0) {
- if_rele(p);
- return (error);
- }
- vid = vlr.vlr_tag;
- proto = vlr.vlr_proto;
- wildcard = (unit < 0);
- } else {
- p = NULL;
- error = ifc_name2unit(name, &unit);
- if (error != 0)
- return (error);
+ }
+ if ((error = ifc_name2unit(name, &unit)) == 0) {
wildcard = (unit < 0);
+ } else {
+ struct ifnet *p_tmp = vlan_clone_match_ethervid(name, &vid);
+ if (p_tmp != NULL) {
+ subinterface = true;
+ unit = IF_DUNIT_NONE;
+ wildcard = false;
+ if (p != NULL) {
+ if_rele(p_tmp);
+ if (p != p_tmp)
+ error = EINVAL;
+ } else
+ p = p_tmp;
+ }
}
- error = ifc_alloc_unit(ifc, &unit);
if (error != 0) {
if (p != NULL)
if_rele(p);
return (error);
}
+ if (!subinterface) {
+ /* vlanX interface, mark X as busy or allocate new unit # */
+ error = ifc_alloc_unit(ifc, &unit);
+ if (error != 0) {
+ if (p != NULL)
+ if_rele(p);
+ return (error);
+ }
+ }
+
/* In the wildcard case, we need to update the name. */
if (wildcard) {
for (dp = name; *dp != '\0'; dp++);
@@ -1046,7 +1062,8 @@
ifv = malloc(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO);
ifp = ifv->ifv_ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
- ifc_free_unit(ifc, unit);
+ if (!subinterface)
+ ifc_free_unit(ifc, unit);
free(ifv, M_VLAN);
if (p != NULL)
if_rele(p);
@@ -1094,7 +1111,8 @@
ether_ifdetach(ifp);
vlan_unconfig(ifp);
if_free(ifp);
- ifc_free_unit(ifc, unit);
+ if (!subinterface)
+ ifc_free_unit(ifc, unit);
free(ifv, M_VLAN);
return (error);
@@ -1121,9 +1139,11 @@
*/
taskqueue_drain(taskqueue_thread, &ifv->lladdr_task);
NET_EPOCH_WAIT();
+ int unit = ifp->if_dunit;
if_free(ifp);
free(ifv, M_VLAN);
- ifc_free_unit(ifc, ifp->if_dunit);
+ if (unit != IF_DUNIT_NONE)
+ ifc_free_unit(ifc, unit);
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Jan 15, 7:19 AM (2 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15807465
Default Alt Text
D27505.id82886.diff (3 KB)

Event Timeline