diff --git a/gtests/net/packetdrill/config.c b/gtests/net/packetdrill/config.c index 676b2d189ae524edaeafb813644a164c9164aae1..bff0d71efacd9cc2e6c8482829e9149c420a4291 100644 --- a/gtests/net/packetdrill/config.c +++ b/gtests/net/packetdrill/config.c @@ -63,6 +63,7 @@ enum option_codes { OPT_UDP_ENCAPS, #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) OPT_TUN_DEV, + OPT_PERSISTENT_TUN_DEV, #endif }; @@ -96,6 +97,7 @@ struct option options[] = { { "udp_encapsulation", .has_arg = true, NULL, OPT_UDP_ENCAPS }, #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) { "tun_dev", .has_arg = true, NULL, OPT_TUN_DEV }, + { "persistent_tun_dev", .has_arg = false, NULL, OPT_PERSISTENT_TUN_DEV }, #endif { NULL }, }; @@ -131,6 +133,7 @@ void show_usage(void) "\t[--udp_encapsulation=[sctp,tcp]]\n" #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) "\t[--tun_dev=<tun_dev_name>]\n" + "\t[--persistent_tun_dev]\n" #endif "\tscript_path ...\n"); } @@ -345,6 +348,20 @@ void finalize_config(struct config *config) die("wire_server_ip not specified\n"); } } +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + if ((config->tun_device == NULL) && + (config->persistent_tun_device == true)) { + die("tun_dev not specified\n"); + } + if ((config->is_wire_client) || (config->is_wire_server)){ + if (config->tun_device != NULL) { + die("tun_dev specified specified\n"); + } + if (config->persistent_tun_device == true) { + die("persistent_tun_dev requested\n"); + } + } +#endif } /* Expect that arg is comma-delimited, allowing for spaces. */ @@ -498,6 +515,9 @@ static void process_option(int opt, char *optarg, struct config *config, case OPT_TUN_DEV: config->tun_device = strdup(optarg); break; + case OPT_PERSISTENT_TUN_DEV: + config->persistent_tun_device = true; + break; #endif default: show_usage(); diff --git a/gtests/net/packetdrill/config.h b/gtests/net/packetdrill/config.h index 796887dcc49141b6f776edbfa9e79b5bd5c33b67..3ee061d4aa4643e1f8cabdba1cb9fc5456447563 100644 --- a/gtests/net/packetdrill/config.h +++ b/gtests/net/packetdrill/config.h @@ -110,6 +110,7 @@ struct config { /* For local testing using a tun interface. */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) char *tun_device; + bool persistent_tun_device; #endif }; diff --git a/gtests/net/packetdrill/netdev.c b/gtests/net/packetdrill/netdev.c index 83f81964c5e884e20c6dfbfb7d7c3a90c5153ba4..d8c9d54d2f30a0a7eb11b30bd646903afa48cd1d 100644 --- a/gtests/net/packetdrill/netdev.c +++ b/gtests/net/packetdrill/netdev.c @@ -65,6 +65,7 @@ struct local_netdev { int ipv6_control_fd; /* fd for IPv6 configuration of tun interface */ int index; /* interface index from if_nametoindex */ struct packet_socket *psock; /* for sniffing packets (owned) */ + bool persistent; }; struct netdev_ops local_netdev_ops; @@ -88,7 +89,7 @@ static void cleanup_old_device(struct config *config, int result; #endif - if (config->tun_device == NULL) { + if ((config->tun_device == NULL) || config->persistent_tun_device) { return; } asprintf(&cleanup_command, @@ -128,6 +129,7 @@ static void create_device(struct config *config, struct local_netdev *netdev) #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + netdev->persistent = config->persistent_tun_device; if (config->tun_device != NULL) { asprintf(&tun_path, "%s/%s", TUN_DIR, config->tun_device); } else { @@ -351,7 +353,7 @@ static void local_netdev_free(struct netdev *a_netdev) if (netdev->tun_fd >= 0) { close(netdev->tun_fd); #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - if (netdev->name != NULL) { + if ((netdev->name != NULL) && !netdev->persistent) { char *cleanup_command = NULL; asprintf(&cleanup_command,