2424#include "../linux.h"
2525#include <unistd.h>
2626#include <sys/stat.h>
27+ #include <sys/socket.h>
2728#include <errno.h>
2829#include <sys/param.h>
2930#include <sys/types.h>
6869#define KRUN_FLAVOR_AWS_NITRO "aws-nitro"
6970#define KRUN_FLAVOR_SEV "sev"
7071
72+ #define PASST_FD_PARENT 0
73+ #define PASST_FD_CHILD 1
74+
7175struct krun_config
7276{
7377 void * handle ;
@@ -80,6 +84,7 @@ struct krun_config
8084 int32_t ctx_id_awsnitro ;
8185 bool has_kvm ;
8286 bool has_awsnitro ;
87+ int passt_fds [2 ];
8388 yajl_val config_tree ;
8489 bool use_passt ;
8590};
@@ -221,7 +226,7 @@ libkrun_parse_resource_configuration (yajl_val *config_tree, libcrun_container_t
221226 /* Annotations value is not a valid integer. */
222227 error (EXIT_FAILURE , 0 , "krun annotation %s value cannot be converted to an integer" , annotation );
223228
224- if (val <= 0 )
229+ if (val < 0 )
225230 error (EXIT_FAILURE , 0 , "krun annotation %s value must be a positive integer" , annotation );
226231
227232 return val ;
@@ -244,6 +249,7 @@ libkrun_configure_vm (uint32_t ctx_id, void *handle, struct krun_config *kconf,
244249{
245250 runtime_spec_schema_config_schema * def = container -> container_def ;
246251 int32_t (* krun_set_vm_config ) (uint32_t ctx_id , uint8_t num_vcpus , uint32_t ram_mib );
252+ int32_t (* krun_add_net_unixstream ) (uint32_t ctx_id , const char * c_path , int fd , uint8_t * const c_mac , uint32_t features , uint32_t flags );
247253 int cpus , ram_mib , gpu_flags , ret ;
248254 cpu_set_t set ;
249255 const char * path_cpus [] = { "cpus" , (const char * ) 0 };
@@ -293,6 +299,16 @@ libkrun_configure_vm (uint32_t ctx_id, void *handle, struct krun_config *kconf,
293299 return crun_make_error (err , - ret , "could not enable virtio gpu" );
294300 }
295301
302+ if (kconf -> use_passt )
303+ {
304+ krun_add_net_unixstream = dlsym (handle , "krun_add_net_unixstream" );
305+
306+ uint8_t mac [] = { 0x5a , 0x94 , 0xef , 0xe4 , 0x0c , 0xee };
307+ ret = krun_add_net_unixstream (ctx_id , NULL , kconf -> passt_fds [PASST_FD_PARENT ], & mac [0 ], COMPAT_NET_FEATURES , 0 );
308+ if (UNLIKELY (ret < 0 ))
309+ error (EXIT_FAILURE , - ret , "could not set krun net configuration" );
310+ }
311+
296312 if (kconf -> config_tree != NULL )
297313 {
298314 /* Try to configure an external kernel. If the configuration file doesn't
@@ -502,6 +518,73 @@ libkrun_exec (void *cookie, libcrun_container_t *container, const char *pathname
502518 return ret ;
503519}
504520
521+ static int
522+ libkrun_start_passt (void * cookie , libcrun_container_t * container )
523+ {
524+ struct krun_config * kconf = (struct krun_config * ) cookie ;
525+ const char * path_use_passt [] = { "use_passt" , (const char * ) 0 };
526+ pid_t pid ;
527+ char fd_as_str [16 ];
528+ int use_passt ;
529+ int status ;
530+ int null ;
531+ int ret ;
532+
533+ use_passt = libkrun_parse_resource_configuration (& kconf -> config_tree , container , "krun.use_passt" , path_use_passt );
534+ if (use_passt > 0 )
535+ kconf -> use_passt = 1 ;
536+ else
537+ return 0 ;
538+
539+ ret = socketpair (AF_UNIX , SOCK_STREAM , 0 , kconf -> passt_fds );
540+ if (UNLIKELY (ret < 0 ))
541+ return ret ;
542+ snprintf (fd_as_str , sizeof (fd_as_str ), "%d" , kconf -> passt_fds [PASST_FD_CHILD ]);
543+
544+ char * const argv [] = {
545+ (char * ) "passt" ,
546+ (char * ) "--no-dhcp-dns" ,
547+ (char * ) "-t" ,
548+ (char * ) "all" ,
549+ (char * ) "-u" ,
550+ (char * ) "all" ,
551+ (char * ) "--fd" ,
552+ fd_as_str ,
553+ NULL
554+ };
555+
556+ pid = fork ();
557+ if (pid < 0 )
558+ return pid ;
559+ else if (pid == 0 )
560+ {
561+ close (kconf -> passt_fds [PASST_FD_PARENT ]);
562+
563+ null = open ("/dev/null" , O_WRONLY );
564+ if (null == -1 )
565+ _exit (EXIT_FAILURE );
566+
567+ // Redirect passt's stdout and stderr to /dev/null, as closing them here
568+ // instead will cause passt to exit with an error.
569+ dup2 (null , STDOUT_FILENO );
570+ dup2 (null , STDERR_FILENO );
571+ close (null );
572+
573+ execvp ("passt" , argv );
574+ // Only reachable on error.
575+ _exit (EXIT_FAILURE );
576+ }
577+
578+ close (kconf -> passt_fds [PASST_FD_CHILD ]);
579+
580+ // Wait for passt to daemonize itself.
581+ waitpid (pid , & status , 0 );
582+ if (! (WIFEXITED (status )) || WEXITSTATUS (status ) != 0 )
583+ return -1 ;
584+
585+ return 0 ;
586+ }
587+
505588/* libkrun_create_kvm_device: explicitly adds kvm device. */
506589static int
507590libkrun_configure_container (void * cookie , enum handler_configure_phase phase ,
@@ -567,6 +650,10 @@ libkrun_configure_container (void *cookie, enum handler_configure_phase phase,
567650 if (phase != HANDLER_CONFIGURE_AFTER_MOUNTS )
568651 return 0 ;
569652
653+ ret = libkrun_start_passt (cookie , container );
654+ if (UNLIKELY (ret < 0 ))
655+ return crun_make_error (err , errno , "start passt" );
656+
570657 /* Do nothing if /dev/kvm is already present in spec */
571658 for (i = 0 ; i < def -> linux -> devices_len ; i ++ )
572659 {
@@ -838,6 +925,35 @@ libkrun_modify_oci_configuration (void *cookie arg_unused, libcrun_context_t *co
838925 return 0 ;
839926}
840927
928+ static int
929+ libkrun_close_fds (void * cookie , libcrun_container_t * container , int preserve_fds , libcrun_error_t * err )
930+ {
931+ struct krun_config * kconf = (struct krun_config * ) cookie ;
932+ int first_fd_to_close = preserve_fds + 3 ;
933+ int passt_fd ;
934+ int i ;
935+
936+ if (kconf -> use_passt )
937+ {
938+ passt_fd = kconf -> passt_fds [PASST_FD_PARENT ];
939+
940+ if (first_fd_to_close <= passt_fd )
941+ {
942+ for (i = first_fd_to_close ; i < passt_fd ; i ++ )
943+ {
944+ // If we're closing proc_fd, make sure to invalidate it.
945+ if (i == container -> proc_fd )
946+ container -> proc_fd = -1 ;
947+ close (i );
948+ }
949+
950+ first_fd_to_close = passt_fd + 1 ;
951+ }
952+ }
953+
954+ return mark_or_close_fds_ge_than (container , first_fd_to_close , true, err );
955+ }
956+
841957struct custom_handler_s handler_libkrun = {
842958 .name = "krun" ,
843959 .alias = NULL ,
@@ -847,6 +963,7 @@ struct custom_handler_s handler_libkrun = {
847963 .run_func = libkrun_exec ,
848964 .configure_container = libkrun_configure_container ,
849965 .modify_oci_configuration = libkrun_modify_oci_configuration ,
966+ .close_fds = libkrun_close_fds ,
850967};
851968
852969#endif
0 commit comments