1818#include <fcntl.h>
1919#include <sys/socket.h>
2020#include <sys/un.h>
21- #include <net/ethernet.h>
2221#include <netinet/ip.h>
23- #include <netinet/ether.h>
2422#include <linux/if_ether.h>
2523#include <linux/if_packet.h>
2624#include <sys/wait.h>
3937#define ID_MAX 2
4038
4139#define TOKEN_IFNAME "ifname"
40+ #define TOKEN_SCRIPT "ifup"
4241
4342#define TRANS_RAW "raw"
4443#define TRANS_RAW_LEN strlen(TRANS_RAW)
5554
5655#define MAX_UN_LEN 107
5756
57+ static const char padchar [] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
58+ static const char * template = "tapXXXXXX" ;
59+
5860/* This is very ugly and brute force lookup, but it is done
5961 * only once at initialization so not worth doing hashes or
6062 * anything more intelligent
@@ -191,16 +193,21 @@ static int create_raw_fd(char *iface, int flags, int proto)
191193 return err ;
192194}
193195
196+
194197static struct vector_fds * user_init_tap_fds (struct arglist * ifspec )
195198{
196- int fd = -1 ;
199+ int fd = -1 , i ;
197200 char * iface ;
198201 struct vector_fds * result = NULL ;
202+ bool dynamic = false;
203+ char dynamic_ifname [IFNAMSIZ ];
204+ char * argv [] = {NULL , NULL , NULL , NULL };
199205
200206 iface = uml_vector_fetch_arg (ifspec , TOKEN_IFNAME );
201207 if (iface == NULL ) {
202- printk (UM_KERN_ERR "uml_tap: failed to parse interface spec\n" );
203- goto tap_cleanup ;
208+ dynamic = true;
209+ iface = dynamic_ifname ;
210+ srand (getpid ());
204211 }
205212
206213 result = uml_kmalloc (sizeof (struct vector_fds ), UM_GFP_KERNEL );
@@ -214,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
214221 result -> remote_addr_size = 0 ;
215222
216223 /* 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 );
217241
218- fd = create_tap_fd ( iface );
219- if (fd < 0 ) {
220- printk ( UM_KERN_ERR "uml_tap: failed to create tun interface\n" ) ;
221- 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 ) ;
222246 }
223- result -> tx_fd = fd ;
224- result -> rx_fd = fd ;
247+
225248 return result ;
226249tap_cleanup :
227250 printk (UM_KERN_ERR "user_init_tap: init failed, error %d" , fd );
@@ -233,6 +256,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
233256{
234257 char * iface ;
235258 struct vector_fds * result = NULL ;
259+ char * argv [] = {NULL , NULL , NULL , NULL };
236260
237261 iface = uml_vector_fetch_arg (ifspec , TOKEN_IFNAME );
238262 if (iface == NULL ) {
@@ -266,6 +290,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
266290 "uml_tap: failed to create paired raw socket: %i\n" , result -> rx_fd );
267291 goto hybrid_cleanup ;
268292 }
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+ }
269299 return result ;
270300hybrid_cleanup :
271301 printk (UM_KERN_ERR "user_init_hybrid: init failed" );
@@ -332,7 +362,7 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
332362 }
333363 switch (id ) {
334364 case ID_BESS :
335- if (connect (fd , remote_addr , sizeof (struct sockaddr_un )) < 0 ) {
365+ if (connect (fd , ( const struct sockaddr * ) remote_addr , sizeof (struct sockaddr_un )) < 0 ) {
336366 printk (UM_KERN_ERR "bess open:cannot connect to %s %i" , remote_addr -> sun_path , - errno );
337367 goto unix_cleanup ;
338368 }
@@ -399,8 +429,7 @@ static struct vector_fds *user_init_fd_fds(struct arglist *ifspec)
399429fd_cleanup :
400430 if (fd >= 0 )
401431 os_close_file (fd );
402- if (result != NULL )
403- kfree (result );
432+ kfree (result );
404433 return NULL ;
405434}
406435
@@ -410,6 +439,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
410439 int err = - ENOMEM ;
411440 char * iface ;
412441 struct vector_fds * result = NULL ;
442+ char * argv [] = {NULL , NULL , NULL , NULL };
413443
414444 iface = uml_vector_fetch_arg (ifspec , TOKEN_IFNAME );
415445 if (iface == NULL )
@@ -432,6 +462,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
432462 result -> remote_addr = NULL ;
433463 result -> remote_addr_size = 0 ;
434464 }
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+ }
435470 return result ;
436471raw_cleanup :
437472 printk (UM_KERN_ERR "user_init_raw: init failed, error %d" , err );
@@ -789,10 +824,12 @@ void *uml_vector_user_bpf(char *filename)
789824 return false;
790825 }
791826 bpf_prog = uml_kmalloc (sizeof (struct sock_fprog ), UM_GFP_KERNEL );
792- if (bpf_prog ! = NULL ) {
793- bpf_prog -> len = statbuf . st_size / sizeof ( struct sock_filter );
794- bpf_prog -> filter = NULL ;
827+ if (bpf_prog = = NULL ) {
828+ printk ( KERN_ERR "Failed to allocate bpf prog buffer" );
829+ return NULL ;
795830 }
831+ bpf_prog -> len = statbuf .st_size / sizeof (struct sock_filter );
832+ bpf_prog -> filter = NULL ;
796833 ffd = os_open_file (filename , of_read (OPENFLAGS ()), 0 );
797834 if (ffd < 0 ) {
798835 printk (KERN_ERR "Error %d opening bpf file" , - errno );
0 commit comments