[Raspberry PI CM4] 桥接两个物理网卡实现PN故障模拟

本文介绍如何使用树莓派CM4 + 双网口扩展板 实现PN 故障模拟功能
null

创建桥接


本章节介绍如何使用nmcli 工具设置桥接,[参考资料](https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-headless-raspberry-pi "参考资料")
  • 创建一个桥接
sudo nmcli connection add type bridge con-name 'Bridge' ifname bridge0

  • 将网卡添加到桥接配置中

将eth0 和 eth1 网卡分别添加到桥接

sudo nmcli connection add type ethernet slave-type bridge con-name 'Ethernet0' ifname eth0 master bridge0

sudo nmcli connection add type ethernet slave-type bridge con-name 'Ethernet1' ifname eth1 master bridge0
  • 设置桥接的IP地址
sudo nmcli connection modify "Bridge" ipv4.method manual ipv4.addresses 192.168.10.50/24
  • 启动生效桥接
sudo nmcli connection up Bridge

🍭 配置好后,这些配置重启不会丢失,无需再次配置


安装管理和配置桥接的命令行工具brctl

sudo apt install bridge-utils

查看当前故障模拟规则

sudo tc -s qdisc show dev eth1

清除故障模拟规则

:exclamation: 设置新规则之前,需要清除之前设置的规则!

sudo tc qdisc del dev eth1 root

桥接模拟延时抖动

执行以下命令,可模拟eth1网卡延迟+抖动

  • PN 周期是4ms的情况下,添加4ms延时,将导致Jitter增大或者单次丢包
sudo tc qdisc add dev eth1 root netem delay 4ms 1ms
  • PN 周期是4ms的情况下,添加20ms延时,将导致连续丢包和连接超时断开
sudo tc qdisc add dev eth1 root netem delay 20ms 1ms
  • PN 周期是4ms的情况下,添加200ms延时,将导致连接超时断开
sudo tc qdisc add dev eth1 root netem delay 200ms 20ms

桥接模拟丢包

执行以下命令,可模拟eth1网卡丢包(百分比)

sudo tc qdisc add dev eth1 root netem loss 30%

桥接模拟延时+丢包

执行以下命令,可模拟eth1网卡丢包50%

sudo tc qdisc add dev eth1 root netem delay 20ms 5ms loss 30%

在树莓派搭建网页测试环境触发故障模拟

安装flask (轻量级Web框架)

# 创建虚拟环境
python3 -m venv ~/webctrl

# 激活环境
source ~/webctrl/bin/activate

#在虚拟环境中安装 Flask
pip3 install flask

创建网页内容

在用户根目录 /home/wef/ 下创建 web_control.py 文件,并编辑

sudo nano web_control.py

输入以下内容

from flask import Flask, render_template_string, request
import subprocess
app = Flask(__name__)


# HTML页面(内嵌模板)
HTML = '''
<!DOCTYPE html>
<html>
<head>
    <title>PN 故障模拟器</title>
</head>
<body>
    <h1>树莓派控制面板</h1>
    <button onclick="runCommand('start2ms')">抖动</button>
    <button onclick="runCommand('start7ms')">丢包</button>
    <button onclick="runCommand('start15ms')">掉站</button>
    <button onclick="runCommand('start100ms')">频繁掉站</button>
    <button onclick="runCommand('stop')">停止</button>
    <p id="result"></p>
    <script>
        function runCommand(cmd) {
            fetch('/run?cmd=' + cmd)
                .then(response => response.text())
                .then(data => {
                    document.getElementById("result").innerText = data;
                });
        }
    </script>
</body>
</html>
'''



@app.route('/')
def home():
    return render_template_string(HTML)
@app.route('/run')
def run_command():
    cmd = request.args.get('cmd')
    try:
        if cmd == 'start2ms':
            output = subprocess.check_output("sudo tc qdisc add dev eth1 root netem delay 3ms 1ms", shell=True, text=True)
        elif cmd == 'start7ms':
            output = subprocess.check_output("sudo tc qdisc add dev eth1 root netem delay 7ms", shell=True, text=True)
        elif cmd == 'start15ms':
            output = subprocess.check_output("sudo tc qdisc add dev eth1 root netem delay 15ms", shell=True, text=True)
        elif cmd == 'start100ms':
            output = subprocess.check_output("sudo tc qdisc add dev eth1 root netem delay 100ms", shell=True, text=True)
        elif cmd == 'stop':
            output = subprocess.check_output("sudo tc qdisc del dev eth1 root", shell=True, text=True)
        else:
            output = "unknow cmd"
        return output
    except Exception as e:
        return f"error: {str(e)}"
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)  # 允许局域网访问

ctrl+x 保存退出
增加文件的执行权限

sudo chmod 777 web_control.py

flask 开机自启动,并执行web_control.py 内容

创建systemd服务:

sudo nano /etc/systemd/system/web_control.service

输入以下内容

[Unit]
Description=Web Control Service
After=network.target
[Service]

ExecStart=/home/wef/webctrl/bin/python3 /home/wef/web_control.py
Restart=always
[Install]
WantedBy=multi-user.target

ctrl+x 保存退出

启用服务

sudo systemctl enable webcontrol.service
sudo systemctl start webcontrol.service

输入树莓派的IP+端口5000,打开如下界面

webserver

可以点击相应的按钮,执行不同故障模拟命令

返回列表

上一篇:Ixxat CAN 接口状态

没有最新的文章了...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。