Commit Diff


commit - 21775861a453dd25aacb50e76637bdec1d1a31cf
commit + d10e23a528ae43f18f5bf001222e460c311960a2
blob - 031502710a5c7be123a4d9e6bd7367f75378b4f7
blob + 1b063c52295dd15d9794bea9d3dc0f136ad34913
--- if.c
+++ if.c
@@ -2345,7 +2345,8 @@ intrtlabel(char *ifname, int ifs, int argc, char **arg
 int
 intparent(char *ifname, int ifs, int argc, char **argv)
 {
-	int set;
+	int set, ret;
+	unsigned long cmd;
 	struct if_parent ifp;
 
 	if (NO_ARG(argv[0])) {
@@ -2374,9 +2375,22 @@ intparent(char *ifname, int ifs, int argc, char **argv
 		return 0;
 	}
 
-	if (ioctl(ifs, set ? SIOCSIFPARENT : SIOCDIFPARENT, &ifp) == -1)
-		printf("%% intparent: SIOC%sIFPARENT: %s\n", set ? "S" : "D",
-		    strerror(errno));
+	cmd = (set ? SIOCSIFPARENT : SIOCDIFPARENT);
+	ret = ioctl(ifs, cmd, &ifp);
+	if (ret == -1) {
+		if (errno == EBUSY) {
+			int flags = get_ifflags(ifname, ifs);
+			if (flags & IFF_UP) {
+				/* Toggle interface down and retry. */
+				set_ifflags(ifname, ifs, flags & ~IFF_UP);
+				ret = ioctl(ifs, cmd, &ifp);
+				set_ifflags(ifname, ifs, flags);
+			}
+		}
+		if (ret == -1)
+			printf("%% intparent: SIOC%sIFPARENT: %s\n",
+			    set ? "S" : "D", strerror(errno));
+	}
 
 	return 0;
 }