Native ns-3 support for generating Flent tests and traces compatible with the Flent GUI, to support network benchmarking studies in ns-3.
Flent (the Flexible Network Tester) is a network benchmarking tool, written in Python, that wraps well-known benchmarking tools such as netperf and iperf into aggregate, repeatable tests — including a family of tests for bufferbloat. A basic Flent Application already existed in ns-3 as a wrapper around existing ns-3 applications; this project's job was to bring that wrapper up to date, check its output against Linux network namespaces output, and get it into ns-3 mainline.
Concretely, the project had four goals: (1) update the prior implementation to match current ns-3-dev, (2) integrate a JSON library for Flent-style result handling, (3) validate the correctness of Flent results produced by ns-3 against those obtained from a real Linux network namespace environment, and (4) add more Flent-style test examples useful to ns-3 users. As the project brief put it: the goal is to merge the Flent Application API into ns-3 mainline, not the app store.
About me — I'm a third-year undergraduate studying Mathematics and Computing at the Indian Institute of Technology, Guwahati. Alongside my interest in computer networks, I'm a competitive programmer and full-stack developer, and this project was a chance to bring those together in service of the ns-3 community.
Working branches: GSoC-2026-flent-application (core application work) and nlohmann-json (JSON library vendoring), both on gitlab.com/k.kedar/ns-3-dev.
All work for this project was developed on GitLab and submitted toward the ns-3 mainline. Below are the primary merge requests and tracking links:
| Type | Description | Merge Request | Commits |
|---|---|---|---|
| Main Project MR | The core application, JSON integration, validation tests, and documentation. Commits on both working branches were squashed for a clean commit history before submission. | ns3::FlentApplication Core (#2968) |
All Commits Commit #1 Commit #2 |
| Dependency MR | A draft MR opened during community bonding to vendor nlohmann/json into the ns-3 third-party/ directory, following a proposal to the ns-developers mailing list that was approved for this and future ns-3 projects. |
Vendor nlohmann/json (#2875) | Commits |
| Dependency MR | MR to add Tos attribute support to the packet-sink application. |
Add Tos attribute to packet-sink (#2963) | Commits |
| Tracking | Work Items Board tracking project milestones and To-Dos. | GitLab Tracker | - |
The final commits focused on cleaning up the code for upstream integration. This included running check-style-clang-format.py for formatting, addressing clang-tidy warnings such as missing override specifiers, adding SPDX license identifiers to all new files, and standardizing Doxygen comments with @ tags and parameter documentation.
This is a summary — the full week-by-week breakdown lives on the project wiki page.
Set the project's validation strategy with mentors (Linux network namespaces over VMs) and got ns-developers approval to vendor nlohmann/json. Ran a gap analysis against real Flent .conf files to scope what the port would need, and moved tracking onto a GitLab Work Items board.
Migrated to nlohmann/json, stood up the netns validation testbed, and worked through the core correctness bugs: the ping application lifecycle, the ping trace source, the inverted maxDist branch in ProcessRawValues, and DSCP marking on the return path. A throughput regression on ns-3.40/3.41 (~44 → 41.4 Mbps) turned out to be a legacy calibration issue rather than a real regression, and early ns-3-vs-Flent plot comparisons showed broadly similar results with a few gaps flagged for follow-up.
Confirmed the ns-3 output matched the Linux reference plots and closed out the last correctness bug (UDP ping arrays). The remainder of the phase went into mainline readiness: a reorganized self-contained test suite, deterministic timestamps, richer JSON metadata, and a full formatting/documentation cleanup pass, ending with the final merge request (#2968).
Most of the debugging time went into the following bugs. All of those are fixed now, each checked either against upstream Flent's own logic or against a real Linux run.
| Symptom | Root cause | Status |
|---|---|---|
| ping test in StartApplication was not being initiated | The ping branch of StartApplication was not calling Start()/Stop() on its ApplicationContainer — the tcp_upload, tcp_download, and rrul branches did; this one just didn't. |
resolved |
Ping results always empty, averages showing up as -nan |
The trace callback was listening on an "Rx" trace source that no longer exist on ns-3's Ping application. Changed the code to use "Rtt" and updated the function signature to (uint16_t seq, Time rtt) to match the change and align with the current ns-3. |
resolved |
| Aggregated stats came out wrong, but not obviously so | A maxDist tightening branch in ProcessRawValues had its condition backwards — tightening when a previous point existed instead of when one didn't, the exact opposite of upstream Flent's aggregators.py. |
resolved |
| DSCP markings were not being applied to TCP ACKs and UDP echo replies | TCP ACKs and UDP echo replies both came back as CS0 regardless of the flow's actual class. Traced it through SetAttribute -> m_tos -> SetIpTos -> SocketIpTosTag -> Ipv4L3Protocol — UdpEchoServer already handled Tos correctly, PacketSink had the attribute but it was removed in a refactor in one of the earlier release. |
resolved |
| Throughput dropped on newer ns-3 releases | ~44 Mbps on 3.36–3.39 became ~41.4 Mbps on 3.40/3.41. Replaying the same logic against 3.36.1 showed it wasn't a regression at all. the original ProcessRawValues had a calibration bug that had been there the whole time. |
resolved |
| UDP ping arrays stayed empty in the RRUL output | UdpEchoClient was still using the deprecated RemoteAddress/RemotePort attributes, which compile fine but leave the port at 0. Switched to the unified Remote attribute with InetSocketAddress. |
resolved |
| Test macros wouldn't compile across test cases | NS_TEST_ASSERT needs protected access that a shared helper function didn't have. Solved it with a small FlentTestCase base class that all the test cases inherit from. |
resolved |
| Repeated runs disagreed with each other by up to a second | FlentApplication was timestamping off whatever clock happened to be running, and losing precision to integer division on top of that. Added a T0 attribute with a fixed default timestamp and switched the math to floating point. |
resolved |
In addition to resolving these bugs, several smaller improvements were made while preparing the code for upstream integration. The nlohmann/json CMake configuration was updated to copy the library into the build tree instead of only adding it to the include path, and its MIT license was added to the LICENSES/ directory. The test suite was also simplified, replacing six order-dependent tests with four independent test cases that each write to their own temporary directory using CreateTempDirFilename(), preventing leftover files from causing false test passes. --retain option can be used to preserve the generated output when needed for debugging. A minor formatting issue in the generated DATA_FILENAME metadata, which left stray hyphens in filenames, was also corrected. Finally, the codebase was polished for upstream submission by applying clang-format, addressing clang-tidy warnings such as missing override specifiers, adding SPDX license identifiers, standardizing Doxygen comments with @ tags, and removing outdated Emacs modelines and unused code.
A simulator can be internally consistent and still wrong, so correctness was checked against a real Linux network stack rather than asserted.
netns), approved over virtual machines during community bonding, with hardware offloading disabled so that the kernel processed packets in a manner consistent with the simulator..flent.gz result files and visualized with the Flent GUI as the reference to compare against.flent-example.cc extended with a --tcpType command-line argument so TCP Cubic plots at 10 ms and 80 ms RTT could be generated without recompiling.netns environment the following week confirmed the ns-3 output lined up with the reference plots.# clone the repo and check out the working branch
git clone https://gitlab.com/k.kedar/ns-3-dev.git
cd ns-3-dev
git checkout GSoC-2026-flent-application
# configure and build
./ns3 configure --enable-tests --enable-examples
./ns3 build
# run the Flent example
./ns3 run src/applications/examples/flent-example.cc
# run the full validation suite
./ns3 run src/applications/examples/flent-application-test-suite.cc
# run the tests directly; --retain keeps generated output for inspection
./test.py -s flent-application --retain
A huge thanks to my mentors, Mohit P. Tahiliani and Tom Henderson, for guiding me throughout GSoC, sharing invaluable resources, sharing debugging techniques during our meetings, and helping me grow as a developer. I am grateful for their thorough code reviews and suggestions to proceed in the right direction. Thanks also to the ns-developers mailing list for approving the nlohmann/json proposal, and to the ns-3 community and Google for this amazing opportunity.