# Modernizing OpenNet: Bringing a 2014 SDN Emulator to Ubuntu 22.04
**TL;DR**: OpenNet, an SDN emulator integrating Mininet and ns-3, was stuck on Ubuntu 14.04 with Python 2. This project modernizes it for Ubuntu 22.04+ with Docker support, Python 3 compatibility, and ns-3.41 bindings. Get started in 3 commands:
```bash
git clone https://github.com/thc1006/OpenNet.git
```
```bash
cd OpenNet
docker build -t opennet:ns3-modern -f docker/Dockerfile.ns3-modern .
```
---
## The Problem
OpenNet is a powerful SDN research tool that combines Mininet (Python-based SDN emulator) with ns-3 (C++ network simulator). It enables researchers to run Mininet topologies with realistic wireless models (WiFi, LTE) from ns-3.
However, the original project had hard dependencies on:
| Dependency | Original Version | Status in 2024 |
|------------|------------------|----------------|
| Ubuntu | 14.04 LTS | EOL since 2019 |
| Python | 2.7 | EOL since 2020 |
| ns-3 | 3.22 | Released 2015 |
| GCC | 4.x | Incompatible with modern systems |
Running OpenNet on any modern Linux distribution was effectively impossible without significant porting effort.
---
## Technical Challenges
### 1. GCC 11+ Compatibility
ns-3.22 was written for GCC 4.x. Modern GCC (11+) enforces stricter C++ standards:
```cpp
// Error: 'uint32_t' was not declared in this scope
// Fix: Add missing includes
#include <cstdint>
#include <climits>
```
Created `ns3-patch/gcc11-compat.patch` with 50+ header fixes across the ns-3 codebase.
### 2. Python 2 to Python 3 Migration
ns-3.22's WAF build system contained 64 Python 2-specific syntax issues:
```python
# Python 2 (invalid in Python 3)
print >> sys.stderr, "Error message"
except ImportError, e:
# Python 3
print("Error message", file=sys.stderr)
except ImportError as e:
```
Created `ns3-patch/waf-python3.patch` to handle all conversions while maintaining Python 2.6+ backward compatibility.
### 3. ns-3 Python Bindings
The original ns-3.22 used Pybindgen for Python bindings, which requires Python 2. Two solutions:
**Option A**: Legacy container (ns-3.22)
- Mininet + OVS working
- ns-3 C++ examples working
- Python bindings NOT available
**Option B**: Modern container (ns-3.41)
- Full Python 3 bindings via Cppyy
- All ns-3 modules accessible from Python
- OpenNet modules updated for new API
### 4. LTE Patch Circular Dependency
The original `lte.patch` created a circular dependency:
```
fd-net-device -> lte (for TeidDscpMapping)
lte -> fd-net-device (for TapEpcHelper)
```
Analyzed and created two fix approaches:
- **Option A**: New `lte-qos` module to break the cycle
- **Option B**: Callback-based decoupling
### 5. ns-3.41 API Migration
Cppyy bindings use different patterns than Pybindgen:
```python
# ns-3.22 (Pybindgen)
import ns.core
import ns.wifi
ns.core.BooleanValue("true")
# ns-3.41 (Cppyy)
from ns import ns
ns.core.BooleanValue(True)
```
Updated all OpenNet modules (ns3.py, wifi.py, lte.py, opennet.py) for the new API.
---
## Solution Architecture
```
OpenNet Modernization Stack
===========================
+------------------+ +------------------+
| Docker Image | | Docker Image |
| opennet:latest | | opennet:ns3-modern|
+------------------+ +------------------+
| Ubuntu 22.04 | | Ubuntu 22.04 |
| ns-3.22 + patches| | ns-3.41 |
| Mininet + OVS | | Mininet + OVS |
| C++ only | | Full Python 3 |
+------------------+ +------------------+
| |
v v
+------------------------------------------+
| GitHub Actions CI |
| (Automated smoke tests) |
+------------------------------------------+
```
---
## Results
### What Works
| Component | Status |
|-----------|--------|
| Mininet core (all topologies) | Working |
| OVS switches (v2.17.9) | Working |
| ns-3 C++ examples | Working |
| ns-3.41 Python bindings | Working |
| OpenNet module imports | Working |
| Docker builds | Working |
| GitHub Actions CI | Working |
### Performance
- Docker image size: ~4GB
- Build time: ~30 minutes (ns-3.41 with bindings)
- CI smoke tests: Pass
---
## Quick Start
### Standard Image (Mininet + ns-3 C++)
```bash
docker build -t opennet:latest -f docker/Dockerfile .
docker run --rm --privileged opennet:latest --test
docker run --rm -it --privileged opennet:latest --shell
```
### Modern Image (Full Python 3 Support)
```bash
docker build -t opennet:ns3-modern -f docker/Dockerfile.ns3-modern .
# Verify ns-3 Python bindings
docker run --rm opennet:ns3-modern python3 -c "from ns import ns; print(ns.wifi)"
# Verify OpenNet modules
docker run --rm opennet:ns3-modern python3 -c "
import sys
sys.path.insert(0, '/opt/opennet/mininet-py3')
from ns3 import *
print('OpenNet ready')
"
```
---
## Project Structure
```
OpenNet/
├── docker/
│ ├── Dockerfile # ns-3.22 legacy
│ ├── Dockerfile.ns3-modern # ns-3.41 with Cppyy
│ └── entrypoint.sh
├── ns3-patch/
│ ├── gcc11-compat.patch # GCC 11+ fixes
│ ├── waf-python3.patch # Python 3 WAF
│ ├── sta-wifi-scan.patch # WiFi scanning
│ ├── animation-interface.patch
│ └── lte-circular-dependency-fix.patch
├── mininet-py3/
│ ├── ns3.py # Updated for ns-3.41
│ ├── wifi.py
│ ├── lte.py
│ └── opennet.py
├── scripts/
│ ├── bootstrap-ubuntu-22.04.sh
│ └── build-ns3.sh
└── docs/
├── REFACTORING_PLAN.md
└── NS3-PYTHON3-ANALYSIS-REPORT.md
```
---
## Lessons Learned
1. **Containerization first**: Docker provided a reproducible environment for iterative fixes without polluting the host system.
2. **Patch isolation**: Keeping fixes in separate patch files (gcc11-compat, waf-python3, etc.) made debugging easier and preserved upstream compatibility.
3. **Dual-track approach**: Supporting both ns-3.22 (legacy) and ns-3.41 (modern) allows users to choose based on their needs.
4. **CI from day one**: GitHub Actions caught regressions early and documented what actually works.
---
## Known Limitations
- **LTE patches**: Fix available but not yet integrated into default build
- **Time dilation**: Requires custom kernel, not supported in Docker
- **NetAnim GUI**: Works but requires X11 forwarding in Docker
---
## Future Work
1. Integrate LTE circular dependency fix into default build
2. Port remaining OpenNet patches to ns-3.41
3. End-to-end WiFi/LTE example verification
4. Performance benchmarking vs original
---
## Links
- **Repository**: https://github.com/thc1006/OpenNet
- **Original Project**: https://github.com/dlinknctu/OpenNet
- **Documentation**: See `docs/` directory
---
## Acknowledgments
This modernization builds upon the original OpenNet project by D-Link and NCTU. The goal is to make this valuable research tool accessible to the current generation of SDN researchers.
---
*Published: November 2025*
> BTW 超哥本來想說叫小易做,但我太無聊xDD