Refactor of SimulationNode.

This prepares for using network emulation manager in Scenario tests.

Bug: webrtc:9510
Change-Id: I6ae1b21790d0bcd2b01a3b293231d0859afc1ac8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132719
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27623}
diff --git a/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc b/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc
index f8b3570..c48d33f 100644
--- a/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc
+++ b/modules/congestion_controller/bbr/bbr_network_controller_unittest.cc
@@ -125,40 +125,36 @@
   config.transport.rates.min_rate = DataRate::kbps(10);
   config.transport.rates.max_rate = DataRate::kbps(1500);
   config.transport.rates.start_rate = DataRate::kbps(300);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(500);
-    c->simulation.delay = TimeDelta::ms(100);
-    c->simulation.loss_rate = 0.0;
-    c->update_frequency = TimeDelta::ms(5);
+  auto send_net = s.CreateMutableSimulationNode([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(500);
+    c->delay = TimeDelta::ms(100);
+    c->loss_rate = 0.0;
   });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto ret_net = s.CreateMutableSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
   auto* client = s.CreateClient("send", config);
-  auto routes =
-      s.CreateRoutes(client, {send_net},
-                     s.CreateClient("recv", CallClientConfig()), {ret_net});
+  auto routes = s.CreateRoutes(client, {send_net->node()},
+                               s.CreateClient("recv", CallClientConfig()),
+                               {ret_net->node()});
   s.CreateVideoStream(routes->forward(), VideoStreamConfig());
 
   s.RunFor(TimeDelta::seconds(25));
   EXPECT_NEAR(client->send_bandwidth().kbps(), 450, 100);
 
-  send_net->UpdateConfig([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(800);
-    c->simulation.delay = TimeDelta::ms(100);
+  send_net->UpdateConfig([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(800);
+    c->delay = TimeDelta::ms(100);
   });
 
   s.RunFor(TimeDelta::seconds(20));
   EXPECT_NEAR(client->send_bandwidth().kbps(), 750, 150);
 
-  send_net->UpdateConfig([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(200);
-    c->simulation.delay = TimeDelta::ms(200);
+  send_net->UpdateConfig([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(200);
+    c->delay = TimeDelta::ms(200);
   });
   ret_net->UpdateConfig(
-      [](NetworkNodeConfig* c) { c->simulation.delay = TimeDelta::ms(200); });
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(200); });
 
   s.RunFor(TimeDelta::seconds(40));
   EXPECT_NEAR(client->send_bandwidth().kbps(), 200, 40);
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
index baa278a..1e53d48 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
@@ -62,30 +62,27 @@
   config.transport.rates.min_rate = DataRate::kbps(10);
   config.transport.rates.max_rate = DataRate::kbps(1500);
   config.transport.rates.start_rate = DataRate::kbps(300);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(500);
-    c->simulation.delay = TimeDelta::ms(100);
-    c->simulation.loss_rate = 0.0;
-    c->update_frequency = TimeDelta::ms(5);
+  auto send_net = s.CreateMutableSimulationNode([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(500);
+    c->delay = TimeDelta::ms(100);
+    c->loss_rate = 0.0;
   });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto ret_net = s.CreateMutableSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
   StatesPrinter* truth = s.CreatePrinter(
       "send.truth.txt", TimeDelta::PlusInfinity(), {send_net->ConfigPrinter()});
-  SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
-      "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
+  SimulatedTimeClient* client =
+      s.CreateSimulatedTimeClient("send", config, {PacketStreamConfig()},
+                                  {send_net->node()}, {ret_net->node()});
 
   truth->PrintRow();
   s.RunFor(TimeDelta::seconds(25));
   truth->PrintRow();
   EXPECT_NEAR(client->target_rate_kbps(), 450, 100);
 
-  send_net->UpdateConfig([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(800);
-    c->simulation.delay = TimeDelta::ms(100);
+  send_net->UpdateConfig([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(800);
+    c->delay = TimeDelta::ms(100);
   });
 
   truth->PrintRow();
@@ -93,12 +90,12 @@
   truth->PrintRow();
   EXPECT_NEAR(client->target_rate_kbps(), 750, 150);
 
-  send_net->UpdateConfig([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(100);
-    c->simulation.delay = TimeDelta::ms(200);
+  send_net->UpdateConfig([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(100);
+    c->delay = TimeDelta::ms(200);
   });
   ret_net->UpdateConfig(
-      [](NetworkNodeConfig* c) { c->simulation.delay = TimeDelta::ms(200); });
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(200); });
 
   truth->PrintRow();
   s.RunFor(TimeDelta::seconds(50));
@@ -241,15 +238,13 @@
   ScopedFieldTrials trial(
       "WebRTC-CongestionWindow/QueueSize:800,MinBitrate:30000/");
   Scenario s("googcc_unit/cwnd_on_delay", false);
-  auto send_net = s.CreateSimulationNode([=](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(1000);
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto send_net =
+      s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) {
+        c->bandwidth = DataRate::kbps(1000);
+        c->delay = TimeDelta::ms(100);
+      });
+  auto ret_net = s.CreateSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
   SimulatedTimeClientConfig config;
   config.transport.cc =
       TransportControllerConfig::CongestionController::kGoogCcFeedback;
@@ -258,7 +253,7 @@
   config.transport.rates.max_rate = DataRate::kbps(2000);
   config.transport.rates.min_rate = DataRate::kbps(10);
   SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
-      "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
+      "send", config, {PacketStreamConfig()}, {send_net->node()}, {ret_net});
 
   s.RunFor(TimeDelta::seconds(10));
   send_net->PauseTransmissionUntil(s.Now() + TimeDelta::seconds(10));
@@ -330,16 +325,13 @@
       "WebRTC-CongestionWindow/QueueSize:200,MinBitrate:30000/");
 
   Scenario s("googcc_unit/padding_limited", false);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([=](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(1000);
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto send_net =
+      s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) {
+        c->bandwidth = DataRate::kbps(1000);
+        c->delay = TimeDelta::ms(100);
+      });
+  auto ret_net = s.CreateSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
   SimulatedTimeClientConfig config;
   config.transport.cc =
       TransportControllerConfig::CongestionController::kGoogCc;
@@ -348,7 +340,7 @@
   config.transport.rates.max_rate = DataRate::kbps(2000);
   config.transport.rates.max_padding_rate = config.transport.rates.max_rate;
   SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
-      "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
+      "send", config, {PacketStreamConfig()}, {send_net->node()}, {ret_net});
   // Run for a few seconds to allow the controller to stabilize.
   s.RunFor(TimeDelta::seconds(10));
 
@@ -374,16 +366,12 @@
   const DataRate kLinkCapacity = DataRate::kbps(100);
   const TimeDelta kBufferBloatDuration = TimeDelta::seconds(10);
   Scenario s("googcc_unit/limit_trial", false);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([=](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = kLinkCapacity;
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
+  auto send_net = s.CreateSimulationNode([=](NetworkSimulationConfig* c) {
+    c->bandwidth = kLinkCapacity;
+    c->delay = TimeDelta::ms(100);
   });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto ret_net = s.CreateSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
   SimulatedTimeClientConfig config;
   config.transport.cc =
       TransportControllerConfig::CongestionController::kGoogCc;
@@ -413,10 +401,9 @@
   SimulatedTimeClientConfig config;
   config.transport.cc =
       TransportControllerConfig::CongestionController::kGoogCcFeedback;
-  NetworkNodeConfig net_conf;
-  net_conf.simulation.bandwidth = DataRate::kbps(500);
-  net_conf.simulation.delay = TimeDelta::ms(100);
-  net_conf.update_frequency = TimeDelta::ms(5);
+  NetworkSimulationConfig net_conf;
+  net_conf.bandwidth = DataRate::kbps(500);
+  net_conf.delay = TimeDelta::ms(100);
   auto send_net = s.CreateSimulationNode(net_conf);
   auto ret_net = s.CreateSimulationNode(net_conf);
   SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
@@ -441,10 +428,9 @@
   SimulatedTimeClientConfig config;
   config.transport.cc =
       TransportControllerConfig::CongestionController::kGoogCcFeedback;
-  NetworkNodeConfig net_conf;
-  net_conf.simulation.bandwidth = DataRate::kbps(500);
-  net_conf.simulation.delay = TimeDelta::ms(100);
-  net_conf.update_frequency = TimeDelta::ms(5);
+  NetworkSimulationConfig net_conf;
+  net_conf.bandwidth = DataRate::kbps(500);
+  net_conf.delay = TimeDelta::ms(100);
   auto send_net = s.CreateSimulationNode(net_conf);
   auto ret_net = s.CreateSimulationNode(net_conf);
   SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
@@ -480,17 +466,13 @@
   config.transport.rates.min_rate = DataRate::kbps(10);
   config.transport.rates.max_rate = DataRate::kbps(1500);
   config.transport.rates.start_rate = DataRate::kbps(300);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(2000);
-    c->simulation.delay = TimeDelta::ms(200);
-    c->simulation.loss_rate = 0.1;
-    c->update_frequency = TimeDelta::ms(5);
+  auto send_net = s.CreateSimulationNode([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(2000);
+    c->delay = TimeDelta::ms(200);
+    c->loss_rate = 0.1;
   });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(200);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto ret_net = s.CreateSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(200); });
   SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
       "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
 
@@ -508,17 +490,13 @@
   config.transport.rates.min_rate = DataRate::kbps(10);
   config.transport.rates.max_rate = DataRate::kbps(5000);
   config.transport.rates.start_rate = DataRate::kbps(300);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(5000);
-    c->simulation.delay = TimeDelta::ms(100);
-    c->simulation.loss_rate = 0.03;
-    c->update_frequency = TimeDelta::ms(5);
+  auto send_net = s.CreateSimulationNode([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(5000);
+    c->delay = TimeDelta::ms(100);
+    c->loss_rate = 0.03;
   });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
+  auto ret_net = s.CreateSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
   SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
       "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
 
@@ -535,18 +513,18 @@
 
   ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
   Scenario s("googcc_unit/safe_reset_low");
-  auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = kLinkCapacity;
-    c->simulation.delay = TimeDelta::ms(10);
+  auto* send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = kLinkCapacity;
+    c->delay = TimeDelta::ms(10);
   });
   // TODO(srte): replace with SimulatedTimeClient when it supports probing.
   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
     c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
     c->transport.rates.start_rate = kStartRate;
   });
-  auto* route = s.CreateRoutes(client, {send_net},
-                               s.CreateClient("return", CallClientConfig()),
-                               {s.CreateSimulationNode(NetworkNodeConfig())});
+  auto* route = s.CreateRoutes(
+      client, {send_net}, s.CreateClient("return", CallClientConfig()),
+      {s.CreateSimulationNode(NetworkSimulationConfig())});
   s.CreateVideoStream(route->forward(), VideoStreamConfig());
   // Allow the controller to stabilize.
   s.RunFor(TimeDelta::ms(500));
@@ -564,18 +542,18 @@
 
   ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
   Scenario s("googcc_unit/safe_reset_high_cut");
-  auto send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = kLinkCapacity;
-    c->simulation.delay = TimeDelta::ms(50);
+  auto send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = kLinkCapacity;
+    c->delay = TimeDelta::ms(50);
   });
   // TODO(srte): replace with SimulatedTimeClient when it supports probing.
   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
     c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
     c->transport.rates.start_rate = kStartRate;
   });
-  auto* route = s.CreateRoutes(client, {send_net},
-                               s.CreateClient("return", CallClientConfig()),
-                               {s.CreateSimulationNode(NetworkNodeConfig())});
+  auto* route = s.CreateRoutes(
+      client, {send_net}, s.CreateClient("return", CallClientConfig()),
+      {s.CreateSimulationNode(NetworkSimulationConfig())});
   s.CreateVideoStream(route->forward(), VideoStreamConfig());
   // Allow the controller to stabilize.
   s.RunFor(TimeDelta::ms(500));
@@ -596,22 +574,22 @@
   const DataRate kStartRate = DataRate::kbps(300);
 
   Scenario s("googcc_unit/safe_reset_high_detect");
-  auto* initial_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = kInitialLinkCapacity;
-    c->simulation.delay = TimeDelta::ms(50);
+  auto* initial_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = kInitialLinkCapacity;
+    c->delay = TimeDelta::ms(50);
   });
-  auto* new_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = kNewLinkCapacity;
-    c->simulation.delay = TimeDelta::ms(50);
+  auto* new_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = kNewLinkCapacity;
+    c->delay = TimeDelta::ms(50);
   });
   // TODO(srte): replace with SimulatedTimeClient when it supports probing.
   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
     c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
     c->transport.rates.start_rate = kStartRate;
   });
-  auto* route = s.CreateRoutes(client, {initial_net},
-                               s.CreateClient("return", CallClientConfig()),
-                               {s.CreateSimulationNode(NetworkNodeConfig())});
+  auto* route = s.CreateRoutes(
+      client, {initial_net}, s.CreateClient("return", CallClientConfig()),
+      {s.CreateSimulationNode(NetworkSimulationConfig())});
   s.CreateVideoStream(route->forward(), VideoStreamConfig());
   // Allow the controller to stabilize.
   s.RunFor(TimeDelta::ms(1000));
@@ -639,18 +617,18 @@
   const DataRate kStartRate = DataRate::kbps(1000);
 
   Scenario s("googcc_unit/pacing_buffer_buildup");
-  auto* net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = kLinkCapacity;
-    c->simulation.delay = TimeDelta::ms(50);
+  auto* net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = kLinkCapacity;
+    c->delay = TimeDelta::ms(50);
   });
   // TODO(srte): replace with SimulatedTimeClient when it supports pacing.
   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
     c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
     c->transport.rates.start_rate = kStartRate;
   });
-  auto* route = s.CreateRoutes(client, {net},
-                               s.CreateClient("return", CallClientConfig()),
-                               {s.CreateSimulationNode(NetworkNodeConfig())});
+  auto* route = s.CreateRoutes(
+      client, {net}, s.CreateClient("return", CallClientConfig()),
+      {s.CreateSimulationNode(NetworkSimulationConfig())});
   s.CreateVideoStream(route->forward(), VideoStreamConfig());
   // Allow some time for the buffer to build up.
   s.RunFor(TimeDelta::seconds(5));
@@ -662,10 +640,10 @@
 TEST_F(GoogCcNetworkControllerTest, NoBandwidthTogglingInLossControlTrial) {
   ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
   Scenario s("googcc_unit/no_toggling");
-  auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(2000);
-    c->simulation.loss_rate = 0.2;
-    c->simulation.delay = TimeDelta::ms(10);
+  auto* send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(2000);
+    c->loss_rate = 0.2;
+    c->delay = TimeDelta::ms(10);
   });
 
   // TODO(srte): replace with SimulatedTimeClient when it supports probing.
@@ -673,9 +651,9 @@
     c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
     c->transport.rates.start_rate = DataRate::kbps(300);
   });
-  auto* route = s.CreateRoutes(client, {send_net},
-                               s.CreateClient("return", CallClientConfig()),
-                               {s.CreateSimulationNode(NetworkNodeConfig())});
+  auto* route = s.CreateRoutes(
+      client, {send_net}, s.CreateClient("return", CallClientConfig()),
+      {s.CreateSimulationNode(NetworkSimulationConfig())});
   s.CreateVideoStream(route->forward(), VideoStreamConfig());
   // Allow the controller to initialize.
   s.RunFor(TimeDelta::ms(250));
@@ -696,18 +674,18 @@
 TEST_F(GoogCcNetworkControllerTest, NoRttBackoffCollapseWhenVideoStops) {
   ScopedFieldTrials trial("WebRTC-Bwe-MaxRttLimit/limit:2s/");
   Scenario s("googcc_unit/rttbackoff_video_stop");
-  auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(2000);
-    c->simulation.delay = TimeDelta::ms(100);
+  auto* send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(2000);
+    c->delay = TimeDelta::ms(100);
   });
 
   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
     c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
     c->transport.rates.start_rate = DataRate::kbps(1000);
   });
-  auto* route = s.CreateRoutes(client, {send_net},
-                               s.CreateClient("return", CallClientConfig()),
-                               {s.CreateSimulationNode(NetworkNodeConfig())});
+  auto* route = s.CreateRoutes(
+      client, {send_net}, s.CreateClient("return", CallClientConfig()),
+      {s.CreateSimulationNode(NetworkSimulationConfig())});
   auto* video = s.CreateVideoStream(route->forward(), VideoStreamConfig());
   // Allow the controller to initialize, then stop video.
   s.RunFor(TimeDelta::seconds(1));
diff --git a/modules/congestion_controller/pcc/pcc_network_controller_unittest.cc b/modules/congestion_controller/pcc/pcc_network_controller_unittest.cc
index f7ee78c..c9e5096 100644
--- a/modules/congestion_controller/pcc/pcc_network_controller_unittest.cc
+++ b/modules/congestion_controller/pcc/pcc_network_controller_unittest.cc
@@ -82,37 +82,33 @@
   config.transport.rates.min_rate = DataRate::kbps(10);
   config.transport.rates.max_rate = DataRate::kbps(1500);
   config.transport.rates.start_rate = DataRate::kbps(300);
-  NetworkNodeConfig net_conf;
-  auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(500);
-    c->simulation.delay = TimeDelta::ms(100);
-    c->simulation.loss_rate = 0.0;
-    c->update_frequency = TimeDelta::ms(5);
+  auto send_net = s.CreateMutableSimulationNode([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(500);
+    c->delay = TimeDelta::ms(100);
   });
-  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
-    c->simulation.delay = TimeDelta::ms(100);
-    c->update_frequency = TimeDelta::ms(5);
-  });
-  SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
-      "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
+  auto ret_net = s.CreateMutableSimulationNode(
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
+  SimulatedTimeClient* client =
+      s.CreateSimulatedTimeClient("send", config, {PacketStreamConfig()},
+                                  {send_net->node()}, {ret_net->node()});
 
   s.RunFor(TimeDelta::seconds(25));
   EXPECT_NEAR(client->target_rate_kbps(), 450, 100);
 
-  send_net->UpdateConfig([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(800);
-    c->simulation.delay = TimeDelta::ms(100);
+  send_net->UpdateConfig([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(800);
+    c->delay = TimeDelta::ms(100);
   });
 
   s.RunFor(TimeDelta::seconds(20));
   EXPECT_NEAR(client->target_rate_kbps(), 750, 150);
 
-  send_net->UpdateConfig([](NetworkNodeConfig* c) {
-    c->simulation.bandwidth = DataRate::kbps(200);
-    c->simulation.delay = TimeDelta::ms(200);
+  send_net->UpdateConfig([](NetworkSimulationConfig* c) {
+    c->bandwidth = DataRate::kbps(200);
+    c->delay = TimeDelta::ms(200);
   });
   ret_net->UpdateConfig(
-      [](NetworkNodeConfig* c) { c->simulation.delay = TimeDelta::ms(200); });
+      [](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(200); });
 
   s.RunFor(TimeDelta::seconds(20));
   EXPECT_NEAR(client->target_rate_kbps(), 200, 40);
diff --git a/test/scenario/network_node.cc b/test/scenario/network_node.cc
index be9ca71..e8f325b 100644
--- a/test/scenario/network_node.cc
+++ b/test/scenario/network_node.cc
@@ -19,15 +19,16 @@
 namespace test {
 namespace {
 constexpr char kDummyTransportName[] = "dummy";
-SimulatedNetwork::Config CreateSimulationConfig(NetworkNodeConfig config) {
+SimulatedNetwork::Config CreateSimulationConfig(
+    NetworkSimulationConfig config) {
   SimulatedNetwork::Config sim_config;
-  sim_config.link_capacity_kbps = config.simulation.bandwidth.kbps_or(0);
-  sim_config.loss_percent = config.simulation.loss_rate * 100;
-  sim_config.queue_delay_ms = config.simulation.delay.ms();
-  sim_config.delay_standard_deviation_ms = config.simulation.delay_std_dev.ms();
+  sim_config.link_capacity_kbps = config.bandwidth.kbps_or(0);
+  sim_config.loss_percent = config.loss_rate * 100;
+  sim_config.queue_delay_ms = config.delay.ms();
+  sim_config.delay_standard_deviation_ms = config.delay_std_dev.ms();
   sim_config.packet_overhead = config.packet_overhead.bytes<int>();
   sim_config.codel_active_queue_management =
-      config.simulation.codel_active_queue_management;
+      config.codel_active_queue_management;
   return sim_config;
 }
 }  // namespace
@@ -44,8 +45,7 @@
 std::unique_ptr<SimulationNode> SimulationNode::Create(
     Clock* clock,
     rtc::TaskQueue* task_queue,
-    NetworkNodeConfig config) {
-  RTC_DCHECK(config.mode == NetworkNodeConfig::TrafficMode::kSimulation);
+    NetworkSimulationConfig config) {
   SimulatedNetwork::Config sim_config = CreateSimulationConfig(config);
   auto network = absl::make_unique<SimulatedNetwork>(sim_config);
   SimulatedNetwork* simulation_ptr = network.get();
@@ -54,7 +54,7 @@
 }
 
 void SimulationNode::UpdateConfig(
-    std::function<void(NetworkNodeConfig*)> modifier) {
+    std::function<void(NetworkSimulationConfig*)> modifier) {
   modifier(&config_);
   SimulatedNetwork::Config sim_config = CreateSimulationConfig(config_);
   simulated_network_->SetConfig(sim_config);
@@ -65,20 +65,18 @@
 }
 
 ColumnPrinter SimulationNode::ConfigPrinter() const {
-  return ColumnPrinter::Lambda("propagation_delay capacity loss_rate",
-                               [this](rtc::SimpleStringBuilder& sb) {
-                                 sb.AppendFormat(
-                                     "%.3lf %.0lf %.2lf",
-                                     config_.simulation.delay.seconds<double>(),
-                                     config_.simulation.bandwidth.bps() / 8.0,
-                                     config_.simulation.loss_rate);
-                               });
+  return ColumnPrinter::Lambda(
+      "propagation_delay capacity loss_rate",
+      [this](rtc::SimpleStringBuilder& sb) {
+        sb.AppendFormat("%.3lf %.0lf %.2lf", config_.delay.seconds<double>(),
+                        config_.bandwidth.bps() / 8.0, config_.loss_rate);
+      });
 }
 
 SimulationNode::SimulationNode(
     Clock* clock,
     rtc::TaskQueue* task_queue,
-    NetworkNodeConfig config,
+    NetworkSimulationConfig config,
     std::unique_ptr<NetworkBehaviorInterface> behavior,
     SimulatedNetwork* simulation)
     : EmulatedNetworkNode(clock, task_queue, std::move(behavior)),
diff --git a/test/scenario/network_node.h b/test/scenario/network_node.h
index 4cb5bcd..e324eba 100644
--- a/test/scenario/network_node.h
+++ b/test/scenario/network_node.h
@@ -45,28 +45,27 @@
   std::function<void()> action_;
 };
 
-// SimulationNode is a EmulatedNetworkNode that expose an interface for changing
-// run time behavior of the underlying simulation.
 class SimulationNode : public EmulatedNetworkNode {
  public:
-  void UpdateConfig(std::function<void(NetworkNodeConfig*)> modifier);
+  void UpdateConfig(std::function<void(NetworkSimulationConfig*)> modifier);
   void PauseTransmissionUntil(Timestamp until);
   ColumnPrinter ConfigPrinter() const;
+  EmulatedNetworkNode* node() { return this; }
 
  private:
   friend class Scenario;
 
   SimulationNode(Clock* clock,
                  rtc::TaskQueue* task_queue,
-                 NetworkNodeConfig config,
+                 NetworkSimulationConfig config,
                  std::unique_ptr<NetworkBehaviorInterface> behavior,
                  SimulatedNetwork* simulation);
   static std::unique_ptr<SimulationNode> Create(Clock* clock,
                                                 rtc::TaskQueue* task_queue,
-                                                NetworkNodeConfig config);
+                                                NetworkSimulationConfig config);
 
   SimulatedNetwork* const simulated_network_;
-  NetworkNodeConfig config_;
+  NetworkSimulationConfig config_;
 };
 
 class NetworkNodeTransport : public Transport {
diff --git a/test/scenario/scenario.cc b/test/scenario/scenario.cc
index ff0cfe5..11ff29d 100644
--- a/test/scenario/scenario.cc
+++ b/test/scenario/scenario.cc
@@ -192,30 +192,33 @@
   simulated_time_clients_.emplace_back(client);
   return client;
 }
-
-SimulationNode* Scenario::CreateSimulationNode(
-    std::function<void(NetworkNodeConfig*)> config_modifier) {
-  NetworkNodeConfig config;
+EmulatedNetworkNode* Scenario::CreateSimulationNode(
+    std::function<void(NetworkSimulationConfig*)> config_modifier) {
+  NetworkSimulationConfig config;
   config_modifier(&config);
   return CreateSimulationNode(config);
 }
 
-SimulationNode* Scenario::CreateSimulationNode(NetworkNodeConfig config) {
-  RTC_DCHECK(config.mode == NetworkNodeConfig::TrafficMode::kSimulation);
+EmulatedNetworkNode* Scenario::CreateSimulationNode(
+    NetworkSimulationConfig config) {
+  return CreateMutableSimulationNode(config);
+}
+
+SimulationNode* Scenario::CreateMutableSimulationNode(
+    std::function<void(NetworkSimulationConfig*)> config_modifier) {
+  NetworkSimulationConfig config;
+  config_modifier(&config);
+  return CreateMutableSimulationNode(config);
+}
+
+SimulationNode* Scenario::CreateMutableSimulationNode(
+    NetworkSimulationConfig config) {
   auto network_node = SimulationNode::Create(clock_, &task_queue_, config);
   SimulationNode* sim_node = network_node.get();
   network_nodes_.emplace_back(std::move(network_node));
   return sim_node;
 }
 
-EmulatedNetworkNode* Scenario::CreateNetworkNode(
-    std::unique_ptr<NetworkBehaviorInterface> behavior) {
-  network_nodes_.emplace_back(
-      new EmulatedNetworkNode(clock_, &task_queue_, std::move(behavior)));
-  EmulatedNetworkNode* network_node = network_nodes_.back().get();
-  return network_node;
-}
-
 void Scenario::TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
                                   size_t num_packets,
                                   size_t packet_size) {
diff --git a/test/scenario/scenario.h b/test/scenario/scenario.h
index cf949df..fb4f0bb 100644
--- a/test/scenario/scenario.h
+++ b/test/scenario/scenario.h
@@ -49,11 +49,13 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
   ~Scenario();
 
-  SimulationNode* CreateSimulationNode(NetworkNodeConfig config);
-  SimulationNode* CreateSimulationNode(
-      std::function<void(NetworkNodeConfig*)> config_modifier);
-  EmulatedNetworkNode* CreateNetworkNode(
-      std::unique_ptr<NetworkBehaviorInterface> behavior);
+  EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config);
+  EmulatedNetworkNode* CreateSimulationNode(
+      std::function<void(NetworkSimulationConfig*)> config_modifier);
+
+  SimulationNode* CreateMutableSimulationNode(NetworkSimulationConfig config);
+  SimulationNode* CreateMutableSimulationNode(
+      std::function<void(NetworkSimulationConfig*)> config_modifier);
 
   CallClient* CreateClient(std::string name, CallClientConfig config);
   CallClient* CreateClient(
diff --git a/test/scenario/scenario_config.cc b/test/scenario/scenario_config.cc
index 223b2a0..82c82c2 100644
--- a/test/scenario/scenario_config.cc
+++ b/test/scenario/scenario_config.cc
@@ -43,15 +43,6 @@
 AudioStreamConfig::Stream::Stream(const AudioStreamConfig::Stream&) = default;
 AudioStreamConfig::Stream::~Stream() = default;
 
-NetworkNodeConfig::NetworkNodeConfig() = default;
-NetworkNodeConfig::NetworkNodeConfig(const NetworkNodeConfig&) = default;
-NetworkNodeConfig::~NetworkNodeConfig() = default;
-
-NetworkNodeConfig::Simulation::Simulation() = default;
-NetworkNodeConfig::Simulation::Simulation(
-    const NetworkNodeConfig::Simulation&) = default;
-NetworkNodeConfig::Simulation::~Simulation() = default;
-
 CrossTrafficConfig::CrossTrafficConfig() = default;
 CrossTrafficConfig::CrossTrafficConfig(const CrossTrafficConfig&) = default;
 CrossTrafficConfig::~CrossTrafficConfig() = default;
diff --git a/test/scenario/scenario_config.h b/test/scenario/scenario_config.h
index 84caa9b..d530d30 100644
--- a/test/scenario/scenario_config.h
+++ b/test/scenario/scenario_config.h
@@ -228,26 +228,14 @@
   } render;
 };
 
-struct NetworkNodeConfig {
-  NetworkNodeConfig();
-  NetworkNodeConfig(const NetworkNodeConfig&);
-  ~NetworkNodeConfig();
-  enum class TrafficMode {
-    kSimulation,
-    kCustom
-  } mode = TrafficMode::kSimulation;
-  struct Simulation {
-    Simulation();
-    Simulation(const Simulation&);
-    ~Simulation();
-    DataRate bandwidth = DataRate::Infinity();
-    TimeDelta delay = TimeDelta::Zero();
-    TimeDelta delay_std_dev = TimeDelta::Zero();
-    double loss_rate = 0;
-    bool codel_active_queue_management = false;
-  } simulation;
+// TODO(srte): Merge this with BuiltInNetworkBehaviorConfig.
+struct NetworkSimulationConfig {
+  DataRate bandwidth = DataRate::Infinity();
+  TimeDelta delay = TimeDelta::Zero();
+  TimeDelta delay_std_dev = TimeDelta::Zero();
+  double loss_rate = 0;
+  bool codel_active_queue_management = false;
   DataSize packet_overhead = DataSize::Zero();
-  TimeDelta update_frequency = TimeDelta::ms(1);
 };
 
 struct CrossTrafficConfig {
diff --git a/test/scenario/scenario_tests/bbr_performance.cc b/test/scenario/scenario_tests/bbr_performance.cc
index 110bf4b..8ab22f8 100644
--- a/test/scenario/scenario_tests/bbr_performance.cc
+++ b/test/scenario/scenario_tests/bbr_performance.cc
@@ -157,14 +157,15 @@
 
   CallClient* alice = s.CreateClient("send", call_config);
   CallClient* bob = s.CreateClient("return", call_config);
-  NetworkNodeConfig net_conf;
-  net_conf.simulation.bandwidth = conf_.scenario.capacity;
-  net_conf.simulation.delay = conf_.scenario.propagation_delay;
-  net_conf.simulation.loss_rate = conf_.scenario.loss_rate;
-  net_conf.simulation.delay_std_dev = conf_.scenario.delay_noise;
-  SimulationNode* send_net = s.CreateSimulationNode(net_conf);
-  SimulationNode* ret_net = s.CreateSimulationNode(net_conf);
-  auto route = s.CreateRoutes(alice, {send_net}, bob, {ret_net});
+  NetworkSimulationConfig net_conf;
+  net_conf.bandwidth = conf_.scenario.capacity;
+  net_conf.delay = conf_.scenario.propagation_delay;
+  net_conf.loss_rate = conf_.scenario.loss_rate;
+  net_conf.delay_std_dev = conf_.scenario.delay_noise;
+  auto* send_net = s.CreateMutableSimulationNode(net_conf);
+  auto* ret_net = s.CreateMutableSimulationNode(net_conf);
+  auto route =
+      s.CreateRoutes(alice, {send_net->node()}, bob, {ret_net->node()});
 
   VideoStreamPair* alice_video =
       s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
diff --git a/test/scenario/scenario_unittest.cc b/test/scenario/scenario_unittest.cc
index c0f8508..eafb4c8 100644
--- a/test/scenario/scenario_unittest.cc
+++ b/test/scenario/scenario_unittest.cc
@@ -23,7 +23,7 @@
   call_client_config.transport.rates.start_rate = DataRate::kbps(300);
   auto* alice = s.CreateClient("alice", call_client_config);
   auto* bob = s.CreateClient("bob", call_client_config);
-  NetworkNodeConfig network_config;
+  NetworkSimulationConfig network_config;
   auto alice_net = s.CreateSimulationNode(network_config);
   auto bob_net = s.CreateSimulationNode(network_config);
   auto route = s.CreateRoutes(alice, {alice_net}, bob, {bob_net});
@@ -62,9 +62,9 @@
   CallClientConfig call_config;
   auto* alice = s.CreateClient("alice", call_config);
   auto* bob = s.CreateClient("bob", call_config);
-  NetworkNodeConfig network_config;
-  network_config.simulation.bandwidth = DataRate::kbps(1000);
-  network_config.simulation.delay = TimeDelta::ms(50);
+  NetworkSimulationConfig network_config;
+  network_config.bandwidth = DataRate::kbps(1000);
+  network_config.delay = TimeDelta::ms(50);
   auto alice_net = s.CreateSimulationNode(network_config);
   auto bob_net = s.CreateSimulationNode(network_config);
   auto route = s.CreateRoutes(alice, {alice_net}, bob, {bob_net});
diff --git a/test/scenario/stats_collection_unittest.cc b/test/scenario/stats_collection_unittest.cc
index 48a4bc3..b4b31cc 100644
--- a/test/scenario/stats_collection_unittest.cc
+++ b/test/scenario/stats_collection_unittest.cc
@@ -15,7 +15,7 @@
 namespace test {
 namespace {
 void CreateAnalyzedStream(Scenario* s,
-                          NetworkNodeConfig network_config,
+                          NetworkSimulationConfig network_config,
                           VideoQualityAnalyzer* analyzer,
                           CallStatsCollectors* collectors) {
   VideoStreamConfig config;
@@ -27,7 +27,7 @@
   auto route =
       s->CreateRoutes(caller, {s->CreateSimulationNode(network_config)},
                       s->CreateClient("callee", CallClientConfig()),
-                      {s->CreateSimulationNode(NetworkNodeConfig())});
+                      {s->CreateSimulationNode(NetworkSimulationConfig())});
   auto* video = s->CreateVideoStream(route->forward(), config);
   auto* audio = s->CreateAudioStream(route->forward(), AudioStreamConfig());
   if (collectors) {
@@ -46,8 +46,8 @@
   CallStatsCollectors stats;
   {
     Scenario s;
-    NetworkNodeConfig good_network;
-    good_network.simulation.bandwidth = DataRate::kbps(1000);
+    NetworkSimulationConfig good_network;
+    good_network.bandwidth = DataRate::kbps(1000);
     CreateAnalyzedStream(&s, good_network, &analyzer, &stats);
     s.RunFor(TimeDelta::seconds(3));
   }
@@ -67,9 +67,9 @@
   CallStatsCollectors stats;
   {
     Scenario s;
-    NetworkNodeConfig bad_network;
-    bad_network.simulation.bandwidth = DataRate::kbps(100);
-    bad_network.simulation.loss_rate = 0.02;
+    NetworkSimulationConfig bad_network;
+    bad_network.bandwidth = DataRate::kbps(100);
+    bad_network.loss_rate = 0.02;
     CreateAnalyzedStream(&s, bad_network, &analyzer, &stats);
     s.RunFor(TimeDelta::seconds(3));
   }
diff --git a/test/scenario/video_stream_unittest.cc b/test/scenario/video_stream_unittest.cc
index 936a518..84384d0 100644
--- a/test/scenario/video_stream_unittest.cc
+++ b/test/scenario/video_stream_unittest.cc
@@ -30,10 +30,11 @@
   frame_counts[1] = 0;
   {
     Scenario s;
-    auto route = s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
-                                {s.CreateSimulationNode(NetworkNodeConfig())},
-                                s.CreateClient("callee", CallClientConfig()),
-                                {s.CreateSimulationNode(NetworkNodeConfig())});
+    auto route =
+        s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
+                       {s.CreateSimulationNode(NetworkSimulationConfig())},
+                       s.CreateClient("callee", CallClientConfig()),
+                       {s.CreateSimulationNode(NetworkSimulationConfig())});
 
     s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
       c->hooks.frame_pair_handlers = {
@@ -78,10 +79,11 @@
   frame_counts[2] = 0;
   {
     Scenario s;
-    auto route = s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
-                                {s.CreateSimulationNode(NetworkNodeConfig())},
-                                s.CreateClient("callee", CallClientConfig()),
-                                {s.CreateSimulationNode(NetworkNodeConfig())});
+    auto route =
+        s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
+                       {s.CreateSimulationNode(NetworkSimulationConfig())},
+                       s.CreateClient("callee", CallClientConfig()),
+                       {s.CreateSimulationNode(NetworkSimulationConfig())});
     s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
       // TODO(srte): Replace with code checking for all simulcast streams when
       // there's a hook available for that.