3737#define ID_MAX 2
3838
3939#define TOKEN_IFNAME "ifname"
40+ #define TOKEN_SCRIPT "ifup"
4041
4142#define TRANS_RAW "raw"
4243#define TRANS_RAW_LEN strlen(TRANS_RAW)
5354
5455#define MAX_UN_LEN 107
5556
57+ static const char padchar [] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
58+ static const char * template = "tapXXXXXX" ;
59+
5660/* This is very ugly and brute force lookup, but it is done
5761 * only once at initialization so not worth doing hashes or
5862 * anything more intelligent
@@ -189,16 +193,21 @@ static int create_raw_fd(char *iface, int flags, int proto)
189193 return err ;
190194}
191195
196+
192197static struct vector_fds * user_init_tap_fds (struct arglist * ifspec )
193198{
194- int fd = -1 ;
199+ int fd = -1 , i ;
195200 char * iface ;
196201 struct vector_fds * result = NULL ;
202+ bool dynamic = false;
203+ char dynamic_ifname [IFNAMSIZ ];
204+ char * argv [] = {NULL , NULL , NULL , NULL };
197205
198206 iface = uml_vector_fetch_arg (ifspec , TOKEN_IFNAME );
199207 if (iface == NULL ) {
200- printk (UM_KERN_ERR "uml_tap: failed to parse interface spec\n" );
201- goto tap_cleanup ;
208+ dynamic = true;
209+ iface = dynamic_ifname ;
210+ srand (getpid ());
202211 }
203212
204213 result = uml_kmalloc (sizeof (struct vector_fds ), UM_GFP_KERNEL );
@@ -212,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
212221 result -> remote_addr_size = 0 ;
213222
214223 /* TAP */
224+ do {
225+ if (dynamic ) {
226+ strcpy (iface , template );
227+ for (i = 0 ; i < strlen (iface ); i ++ ) {
228+ if (iface [i ] == 'X' ) {
229+ iface [i ] = padchar [rand () % strlen (padchar )];
230+ }
231+ }
232+ }
233+ fd = create_tap_fd (iface );
234+ if ((fd < 0 ) && (!dynamic )) {
235+ printk (UM_KERN_ERR "uml_tap: failed to create tun interface\n" );
236+ goto tap_cleanup ;
237+ }
238+ result -> tx_fd = fd ;
239+ result -> rx_fd = fd ;
240+ } while (fd < 0 );
215241
216- fd = create_tap_fd ( iface );
217- if (fd < 0 ) {
218- printk ( UM_KERN_ERR "uml_tap: failed to create tun interface\n" ) ;
219- goto tap_cleanup ;
242+ argv [ 0 ] = uml_vector_fetch_arg ( ifspec , TOKEN_SCRIPT );
243+ if (argv [ 0 ] ) {
244+ argv [ 1 ] = iface ;
245+ run_helper ( NULL , NULL , argv ) ;
220246 }
221- result -> tx_fd = fd ;
222- result -> rx_fd = fd ;
247+
223248 return result ;
224249tap_cleanup :
225250 printk (UM_KERN_ERR "user_init_tap: init failed, error %d" , fd );
@@ -231,6 +256,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
231256{
232257 char * iface ;
233258 struct vector_fds * result = NULL ;
259+ char * argv [] = {NULL , NULL , NULL , NULL };
234260
235261 iface = uml_vector_fetch_arg (ifspec , TOKEN_IFNAME );
236262 if (iface == NULL ) {
@@ -264,6 +290,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
264290 "uml_tap: failed to create paired raw socket: %i\n" , result -> rx_fd );
265291 goto hybrid_cleanup ;
266292 }
293+
294+ argv [0 ] = uml_vector_fetch_arg (ifspec , TOKEN_SCRIPT );
295+ if (argv [0 ]) {
296+ argv [1 ] = iface ;
297+ run_helper (NULL , NULL , argv );
298+ }
267299 return result ;
268300hybrid_cleanup :
269301 printk (UM_KERN_ERR "user_init_hybrid: init failed" );
@@ -407,6 +439,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
407439 int err = - ENOMEM ;
408440 char * iface ;
409441 struct vector_fds * result = NULL ;
442+ char * argv [] = {NULL , NULL , NULL , NULL };
410443
411444 iface = uml_vector_fetch_arg (ifspec , TOKEN_IFNAME );
412445 if (iface == NULL )
@@ -429,6 +462,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
429462 result -> remote_addr = NULL ;
430463 result -> remote_addr_size = 0 ;
431464 }
465+ argv [0 ] = uml_vector_fetch_arg (ifspec , TOKEN_SCRIPT );
466+ if (argv [0 ]) {
467+ argv [1 ] = iface ;
468+ run_helper (NULL , NULL , argv );
469+ }
432470 return result ;
433471raw_cleanup :
434472 printk (UM_KERN_ERR "user_init_raw: init failed, error %d" , err );
0 commit comments