diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c
index 0a7d3751bd667fac6ae65b56133538f363df32ac..54f4ebbdd09d0c67ad960c46b17b7afb5d0ddf42 100644
--- a/gtests/net/packetdrill/run.c
+++ b/gtests/net/packetdrill/run.c
@@ -62,7 +62,11 @@
  * sequence that wait_for_event() must execute while waiting
  * for the next event.
  */
+#if defined(__FreeBSD__)
+const int MAX_SPIN_USECS = 100;
+#else
 const int MAX_SPIN_USECS = 20;
+#endif
 
 static struct state *state = NULL;
 
@@ -328,7 +332,7 @@ void wait_for_event(struct state *state)
 		 * that we know has a fine-grained usleep(), then
 		 * usleep() instead of spinning on the CPU.
 		 */
-#if defined(linux) || defined(__FreeBSD__)
+#if defined(linux)
 		/* Since the scheduler may not wake us up precisely
 		 * when we tell it to, sleep until just before the
 		 * event we're waiting for and then spin.
@@ -337,6 +341,20 @@ void wait_for_event(struct state *state)
 			usleep(wait_usecs - MAX_SPIN_USECS);
 		}
 #endif
+#if defined(__FreeBSD__)
+		/* Since the scheduler may not wake us up precisely
+		 * when we tell it to, sleep until just before the
+		 * event we're waiting for and then spin.
+		 * Since FreeBSD is overshooting by about 10 percent,
+		 * take this into account.
+		 */
+		if (wait_usecs > MAX_SPIN_USECS) {
+			useconds_t delta = (useconds_t)(wait_usecs - MAX_SPIN_USECS);
+
+			delta -= delta >> 3;
+			usleep(delta);
+		}
+#endif
 
 		/* At this point we should only have a millisecond or
 		 * two to wait, so we spin.
diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c
index fa4033bef4b955eaa9ce54068e82db8a117472bb..5a1af9a190b941a1c99be5b0af93b706100b36a7 100644
--- a/gtests/net/packetdrill/run_packet.c
+++ b/gtests/net/packetdrill/run_packet.c
@@ -3274,24 +3274,17 @@ static int do_inbound_script_packet(
 			packet_payload_len(live_packet);
 	}
 
-	if (live_packet->ipv4 != NULL) {
-		if (live_packet->ipv4->src_ip.s_addr == 0) {
-			DEBUGP("live_packet->ipv4->src_ip.s_addr == 0\n");
-			state->socket_under_test = setup_new_child_socket(state, packet);
+	if ((state->socket_under_test == NULL) &&
+	    (((live_packet->ipv4 != NULL) &&
+	      (live_packet->ipv4->src_ip.s_addr == htonl(INADDR_ANY))) ||
+	     ((live_packet->ipv6 != NULL) &&
+	      (IN6_IS_ADDR_UNSPECIFIED(&live_packet->ipv6->src_ip))))) {
 			struct tuple live_inbound;
-			socket_get_inbound(&state->socket_under_test->live, &live_inbound);
-			set_packet_tuple(live_packet, &live_inbound);
-		}
-	}
 
-	if (live_packet->ipv6 != NULL) {
-		if (IN6_IS_ADDR_UNSPECIFIED(&live_packet->ipv6->src_ip)) {
-			DEBUGP("live_packet->ipv6->src_ip.s_addr == 0\n");
+			DEBUGP("live_packet has wildcard source address\n");
 			state->socket_under_test = setup_new_child_socket(state, packet);
-			struct tuple live_inbound;
 			socket_get_inbound(&state->socket_under_test->live, &live_inbound);
 			set_packet_tuple(live_packet, &live_inbound);
-		}
 	}
 
 	/* Inject live packet into kernel. */
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 3f87f607d0b1bb74aa253be2afb4315a46be6673..13f0b086ea4213b023360157ef062d6d4e6ffac2 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -6659,22 +6659,25 @@ void syscalls_free(struct state *state, struct syscalls *syscalls, int about_to_
 		    syscalls->event->line_number);
 	}
 
-	if (status == STATUS_OK) {
+	if (status == STATUS_ERR) {
+		/* Canceling the thread. */
+		DEBUGP("main thread: canceling syscall thread \n");
+		pthread_cancel(syscalls->thread);
+	} else {
 		/* Send a request to terminate the thread. */
 		DEBUGP("main thread: signaling syscall thread to exit\n");
 		syscalls->state = SYSCALL_EXITING;
 		if (pthread_cond_signal(&syscalls->enqueued) != 0)
 			die_perror("pthread_cond_signal");
-
-		/* Release the lock briefly and wait for syscall thread to finish. */
-		run_unlock(state);
-		DEBUGP("main thread: unlocking, waiting for syscall thread exit\n");
-		void *thread_result = NULL;
-		if (pthread_join(syscalls->thread, &thread_result) != 0)
-			die_perror("pthread_cancel");
-		DEBUGP("main thread: joined syscall thread; relocking\n");
-		run_lock(state);
 	}
+	/* Release the lock briefly and wait for syscall thread to finish. */
+	run_unlock(state);
+	DEBUGP("main thread: unlocking, waiting for syscall thread exit\n");
+	void *thread_result = NULL;
+	if (pthread_join(syscalls->thread, &thread_result) != 0)
+		die_perror("pthread_cancel");
+	DEBUGP("main thread: joined syscall thread; relocking\n");
+	run_lock(state);
 	if ((pthread_cond_destroy(&syscalls->idle) != 0) ||
 	    (pthread_cond_destroy(&syscalls->enqueued) != 0) ||
 	    (pthread_cond_destroy(&syscalls->dequeued) != 0)) {