Index: sbin/ifconfig/ifgroup.c =================================================================== --- sbin/ifconfig/ifgroup.c +++ sbin/ifconfig/ifgroup.c @@ -52,12 +52,9 @@ memset(&ifgr, 0, sizeof(ifgr)); strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); - if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) - errx(1, "setifgroup: group names may not end in a digit"); - if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) errx(1, "setifgroup: group name too long"); - if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1 && errno != EEXIST) + if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1) err(1," SIOCAIFGROUP"); } @@ -70,9 +67,6 @@ memset(&ifgr, 0, sizeof(ifgr)); strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); - if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) - errx(1, "unsetifgroup: group names may not end in a digit"); - if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) errx(1, "unsetifgroup: group name too long"); if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1 && errno != ENOENT) Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -1215,6 +1215,7 @@ /* Report the new if_xname back to the userland. */ sprintf(ifname, "%s", ifp->if_xname); + IFNET_WUNLOCK(); prison_free(pr); return (0); } @@ -1274,6 +1275,25 @@ } #endif /* VIMAGE */ +int +if_checkname(const char *name) +{ + struct ifnet *ifp; + struct ifg_group *ifg; + + IFNET_LOCK_ASSERT(); + + TAILQ_FOREACH(ifg, &V_ifg_head, ifg_next) + if (!strncmp(name, ifg->ifg_group, IFNAMSIZ)) + return (EEXIST); + + TAILQ_FOREACH(ifp, &V_ifnet, if_link) + if (!strncmp(name, ifp->if_xname, IFNAMSIZ)) + return (EEXIST); + + return (0); +} + /* * Add a group to an interface */ @@ -1283,15 +1303,13 @@ struct ifg_list *ifgl; struct ifg_group *ifg = NULL; struct ifg_member *ifgm; + struct ifnet *ifp_it; int new = 0; - if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' && - groupname[strlen(groupname) - 1] <= '9') - return (EINVAL); - IFNET_WLOCK(); - TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) - if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) { + + TAILQ_FOREACH(ifp_it, &V_ifnet, if_link) + if (!strncmp(groupname, ifp_it->if_xname, IFNAMSIZ)) { IFNET_WUNLOCK(); return (EEXIST); } @@ -2522,6 +2540,7 @@ while (namelen != 0) sdl->sdl_data[--namelen] = 0xff; IF_ADDR_WUNLOCK(ifp); + IFNET_WUNLOCK(); EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp); /* Announce the return of the interface. */ @@ -3602,12 +3621,25 @@ void if_initname(struct ifnet *ifp, const char *name, int unit) { + char new_name[IFNAMSIZ]; + ifp->if_dname = name; ifp->if_dunit = unit; + + IFNET_WLOCK(); +again: if (unit != IF_DUNIT_NONE) - snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", name, unit); + snprintf(new_name, IFNAMSIZ, "%s%d", name, unit); else - strlcpy(ifp->if_xname, name, IFNAMSIZ); + strlcpy(new_name, name, IFNAMSIZ); + + if (if_checkname(new_name)) { + unit++; + goto again; + } + + strlcpy(ifp->if_xname, new_name, IFNAMSIZ); + IFNET_WUNLOCK(); } int Index: sys/net/if_clone.c =================================================================== --- sys/net/if_clone.c +++ sys/net/if_clone.c @@ -217,8 +217,12 @@ int err; struct ifnet *ifp; - if (ifunit(name) != NULL) + IFNET_RLOCK(); + if (if_checkname(name)) { + IFNET_RUNLOCK(); return (EEXIST); + } + IFNET_RUNLOCK(); if (ifc->ifc_type == SIMPLE) err = ifc_simple_create(ifc, name, len, params); @@ -621,7 +625,9 @@ } snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, *unit); - if (ifunit(name) != NULL) { + IFNET_RLOCK(); + if (if_checkname(name)) { + IFNET_RUNLOCK(); free_unr(ifc->ifc_unrhdr, *unit); if (wildcard) { (*unit)++; @@ -629,6 +635,7 @@ } else return (EEXIST); } + IFNET_RUNLOCK(); IF_CLONE_ADDREF(ifc); Index: sys/net/if_epair.c =================================================================== --- sys/net/if_epair.c +++ sys/net/if_epair.c @@ -767,10 +767,10 @@ *(dp+1) = '\0'; /* Check if 'a' and 'b' interfaces already exist. */ - if (ifunit(name) != NULL) + if (if_checkname(name)) return (EEXIST); *dp = 'a'; - if (ifunit(name) != NULL) + if (if_checkname(name)) return (EEXIST); /* Allocate memory for both [ab] interfaces */ Index: sys/net/if_var.h =================================================================== --- sys/net/if_var.h +++ sys/net/if_var.h @@ -489,6 +489,7 @@ * To assert the ifnet lock, you must know not only whether it's for read or * write, but also whether it was acquired with sleep support or not. */ +#define IFNET_LOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_LOCKED) #define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED) #define IFNET_RLOCK_NOSLEEP_ASSERT() rw_assert(&ifnet_rwlock, RA_RLOCKED) #define IFNET_WLOCK_ASSERT() do { \ @@ -554,6 +555,7 @@ int ifpromisc(struct ifnet *, int); struct ifnet *ifunit(const char *); struct ifnet *ifunit_ref(const char *); +int if_checkname(const char *); int ifa_add_loopback_route(struct ifaddr *, struct sockaddr *); int ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);