Luci-699/SDN-Topology-Change-Detector
GitHub: Luci-699/SDN-Topology-Change-Detector
一个基于Ryu OpenFlow 1.3控制器与Mininet的SDN拓扑变更检测器,实现LLDP发现、MAC学习与实时监控。
Stars: 0 | Forks: 0
# SDN拓扑变更检测器
**使用Ryu OpenFlow控制器 + Mininet的实时拓扑监控与变更检测**
一个基于SDN的系统,能够实时检测网络拓扑变化(交换机/链路上/下线),实现带有OpenFlow流规则的MAC学习交换机,并提供带事件日志的监控功能。
## 问题陈述
在软件定义网络(SDN)中,控制器需要维护网络拓扑的准确视图。链路故障、交换机断开或新设备添加等网络变化必须被实时检测并响应,以确保网络可靠性。
本项目实现了一个使用**Ryu框架**的**OpenFlow 1.3控制器**,其功能包括:
1. 使用**LLDP**(链路层发现协议)发现网络拓扑
2. **实时**检测拓扑变化(交换机加入/离开、链路添加/删除)
3. 实现带有适当流规则安装的**MAC学习交换机**
4. 记录带有时间戳的所有拓扑事件
5. 提供**Web仪表板**用于可视化
### 为何采用此设计?
- **环形拓扑(3台交换机)**:提供路径冗余,支持有意义的拓扑变更测试。当一条链路故障时,流量仍可通过替代路径到达目的地。
- **Ryu控制器**:轻量级、文档完善的Python框架,内置拓扑发现功能。
- **OpenFlow 1.3**:SDN交换机与控制器通信的行业标准。
## 架构
```
+---------------------------------------------+
| Ryu Controller |
| +----------------+ +--------------------+ |
| | Learning Switch | | Topology Detector | |
| | (packet_in) | | (LLDP events) | |
| +----------------+ +--------------------+ |
| +----------------+ +--------------------+ |
| | Flow Monitor | | REST API | |
| | (flow stats) | | (/topology /events)| |
| +----------------+ +--------------------+ |
+-----------------------+---------------------+
| OpenFlow 1.3
+-------------+-------------+
| | |
+----+----+ +----+----+ +----+----+
| s1 |--| s2 |--| s3 |
| (OVS) | | (OVS) | | (OVS) |
+--+---+--+ +--+---+--+ +--+---+--+
| | | | | |
h1 h2 h3 h4 h5 h6
Ring: s1--s2, s2--s3, s3--s1
```
### 关键SDN概念
| 概念 | 描述 |
|------|------|
| **OpenFlow** | 控制器与交换机通信的协议。控制器在交换机上安装流规则。 |
| **表缺失条目(table-miss entry)** | 默认流规则(优先级=0),将未匹配的数据包发送到控制器。 |
| **packet_in** | 当交换机收到匹配表缺失条目的数据包时触发的事件。 |
| **流规则(Flow Rule)** | match(字段) -> action(输出端口)。通过`OFPFlowMod`安装。 |
| **LLDP** | Ryu用于发现交换机间链路的链路层发现协议。 |
| **MAC学习** | 控制器通过观察packet_in中的源MAC地址学习MAC地址对应的端口。 |
## 项目结构
```
orange-project/
+-- controller/
| +-- topology_detector.py # Main Ryu app (learning switch + topology detection)
+-- topology/
| +-- custom_topo.py # Custom Mininet ring topology (3 switches, 6 hosts)
+-- dashboard/
| +-- web_app.py # Flask web dashboard
| +-- templates/index.html # Dashboard UI
| +-- static/style.css # Dark theme styles
+-- tests/
| +-- test_connectivity.sh # Ping tests
| +-- test_throughput.sh # iperf tests
| +-- test_topo_change.sh # Topology change simulation
| +-- dump_flows.sh # Flow table dump script
+-- logs/
| +-- topology_events.log # Event log file (generated at runtime)
+-- screenshots/ # Proof of execution screenshots
+-- requirements.txt
+-- README.md
```
## 设置说明(Ubuntu虚拟机)
### 1. 安装Mininet
```
sudo apt-get update
sudo apt-get install -y mininet openvswitch-switch
```
验证安装:
```
sudo mn --test pingall
```
### 2. 安装Ryu控制器
```
sudo apt-get install -y python3-pip python3-dev
pip3 install ryu
```
验证安装:
```
ryu-manager --version
```
### 3. 安装项目依赖
```
cd orange-project
pip3 install -r requirements.txt
```
### 4. 安装额外测试工具
```
sudo apt-get install -y iperf net-tools
```
## 执行步骤
您需要在Linux虚拟机上打开**3个终端窗口**:
### 终端1:启动Ryu控制器
```
cd orange-project
ryu-manager controller/topology_detector.py --observe-links --verbose
```
`--observe-links`标志启用基于LLDP的拓扑发现。
预期输出:
```
loading app controller/topology_detector.py
loading app ryu.topology.switches
=== Topology Detector Controller Started ===
```
### 终端2:启动Mininet
```
cd orange-project
sudo python3 topology/custom_topo.py
```
预期输出:
```
*** Creating Topology Detector Network
*** Creating switches
*** Creating hosts
*** Starting network
============================================================
SDN Topology Change Detector - Mininet Network
Controller: Ryu at 127.0.0.1:6633
Switches: s1, s2, s3 (ring topology)
Hosts: h1-h6 (2 per switch)
============================================================
mininet>
```
在Ryu终端中,您应该看到:
```
[SWITCH_CONNECTED] Switch s1 connected to controller
[SWITCH_CONNECTED] Switch s2 connected to controller
[SWITCH_CONNECTED] Switch s3 connected to controller
[LINK_ADD] Link UP: s1(port 3) <-> s2(port 3)
[LINK_ADD] Link UP: s2(port 4) <-> s3(port 3)
[LINK_ADD] Link UP: s3(port 4) <-> s1(port 4)
```
### 终端3:启动仪表板(可选)
```
cd orange-project
python3 dashboard/web_app.py
```
在浏览器中打开:`http://:9090`
## 测试与预期输出
### 测试1:连通性(pingall)
在Mininet CLI中:
```
mininet> pingall
```
预期输出:
```
*** Ping: testing ping reachability
h1 -> h2 h3 h4 h5 h6
h2 -> h1 h3 h4 h5 h6
h3 -> h1 h2 h4 h5 h6
h4 -> h1 h2 h3 h5 h6
h5 -> h1 h2 h3 h4 h6
h6 -> h1 h2 h3 h4 h5
*** Results: 0% dropped (30/30 received)
```
### 测试2:流表
```
mininet> sh ovs-ofctl -O OpenFlow13 dump-flows s1
```
预期输出(pingall之后):
```
cookie=0x0, duration=X.Xs, table=0, n_packets=X, n_bytes=X,
priority=1,in_port=1,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02
actions=output:2
cookie=0x0, duration=X.Xs, table=0, n_packets=X, n_bytes=X,
priority=0 actions=CONTROLLER:65535
```
这显示:
- **优先级=1** 的流规则:带有特定匹配/动作的已学习MAC到端口映射
- **优先级=0** 的表缺失条目:捕获未匹配的数据包并发送到控制器
### 测试3:延迟(ping)
```
mininet> h1 ping -c 10 h6
```
预期:显示往返时间(RTT)毫秒数。
### 测试4:吞吐量(iperf)
```
mininet> iperf h1 h6
```
预期:显示以Mbits/sec或Gbits/sec为单位的吞吐量。
### 测试5:拓扑变更检测
```
mininet> link s1 s2 down
```
在Ryu终端中,您应该看到:
```
[LINK_DELETE] Link DOWN: s1(port 3) <-> s2(port 3)
```
然后恢复:
```
mininet> link s1 s2 up
```
在Ryu终端中:
```
[LINK_ADD] Link UP: s1(port 3) <-> s2(port 3)
```
### 测试6:查看事件日志
```
cat logs/topology_events.log
```
预期格式:
```
[2026-04-14 19:30:00] ============================================================
[2026-04-14 19:30:00] SDN Topology Detector - Session Started
[2026-04-14 19:30:00] ============================================================
[2026-04-14 19:30:01] SWITCH_CONNECTED: Switch s1 connected to controller
[2026-04-14 19:30:01] SWITCH_CONNECTED: Switch s2 connected to controller
[2026-04-14 19:30:01] SWITCH_CONNECTED: Switch s3 connected to controller
[2026-04-14 19:30:02] LINK_ADD: Link UP: s1(port 3) <-> s2(port 3)
[2026-04-14 19:30:10] HOST_DISCOVERED: Host 10.0.0.1 (MAC: 00:00:00:00:00:01) found on s1 port 1
[2026-04-14 19:32:00] LINK_DELETE: Link DOWN: s1(port 3) <-> s2(port 3)
[2026-04-14 19:33:00] LINK_ADD: Link UP: s1(port 3) <-> s2(port 3)
```
## 截图 / 执行证明
### 1. 控制器启动与交换机连接
### 2. Mininet拓扑创建
### 3. Pingall结果(0%丢包)
### 4. 流表(ovs-ofctl dump-flows)
### 5. 拓扑变更检测(链路断开/恢复)
### 6. iperf吞吐量结果
### 7. 事件日志文件
### 8. Web仪表板
## 流规则详情
### 表缺失条目(在交换机连接时安装)
```
Match: * (wildcard - matches all packets)
Action: output:CONTROLLER
Priority: 0 (lowest)
Timeout: none (permanent)
```
### 学习到的MAC流规则(在packet_in时安装)
```
Match: in_port=X, eth_src=SRC_MAC, eth_dst=DST_MAC
Action: output:Y
Priority: 1 (higher than table-miss)
idle_timeout: 300 seconds (removed after 5 min inactivity)
hard_timeout: 600 seconds (absolute max 10 min lifetime)
```
### 为什么采用这些参数?
- **优先级=1**:高于表缺失(0),因此特定规则优先匹配
- **idle_timeout=300**:自动清理陈旧条目
- **hard_timeout=600**:即使没有周期性流量,也防止永久陈旧条目
- **匹配 eth_src + eth_dst + in_port**:最精确的L2转发匹配
## 参考
1. Ryu SDN框架文档 - https://ryu.readthedocs.io/
2. OpenFlow 1.3规范 - https://opennetworking.org/
3. Mininet快速入门 - http://mininet.org/walkthrough/
4. Open vSwitch文档 - https://docs.openvswitch.org/
5. "软件定义网络:综合调查" - D. Kreutz等,IEEE 2015
标签:3交换机环, 6主机测试, LLDP, MAC学习, Mininet, Mutation, OpenFlow, OpenFlow 1.3, Python框架, REST API, Ryu控制器, SDN, Web仪表板, 事件日志, 可视化, 拓扑检测, 故障转移测试, 流表安装, 环拓扑, 网络可靠性, 软件定义网络