---
# System prepended metadata

title: 'Modernizing OpenNet: Bringing a 2014 SDN Emulator to Ubuntu 22.04'
tags: [Winlab]

---

# 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