nmcli无法直接配置802.1p优先级,需先用ip link创建VLAN接口,再通过tc+iptables实现PCP标记,或启用网卡硬件VLAN offload;nmcli仅管理IP层参数,不处理帧头级802.1p操作。

Linux 中用 nmcli 无法直接配置 802.1p 优先级位(即以太网帧中的 3-bit Priority Code Point,PCP),因为 nmcli 和 NetworkManager 本身不处理数据链路层的帧标记操作。802.1p 是 VLAN 标签(802.1Q)的一部分,必须在 VLAN 接口上结合流量控制工具(如 tc)或硬件 offload 配合驱动设置 才能生效。
真正可行的路径是:
✅ 先用 ip link 创建带 VLAN ID 的子接口(启用 802.1Q);
✅ 再通过 tc(traffic control)为该接口配置 qdisc + class + filter,将特定流量映射到对应 PCP 值;
✅ 或启用网卡硬件支持的 VLAN priority offload(需驱动和交换机协同)。
确认底层支持前提
-
检查内核是否加载
8021q模块:lsmod | grep 8021q
若无输出,运行
sudo modprobe 8021q,并写入/etc/modules-load.d/8021q.conf实现开机加载。 -
查看网卡是否支持 VLAN offload(尤其是 tx/rx vlan):
ethtool -k eth0 | grep vlan
输出中
rx-vlan-offload和tx-vlan-offload应为on。 确保
iproute2版本 ≥ 4.0(ip -V可查),旧版不支持tc对 VLAN PCP 的精细操作。
创建带优先级能力的 VLAN 接口
假设物理网卡为 eth0,需承载 VLAN 100 并为语音流量打上 PCP=5(高优先级):
# 创建 VLAN 接口(注意:不指定 protocol 默认为 802.1Q) sudo ip link add link eth0 name eth0.100 type vlan id 100 # 启用接口 sudo ip link set eth0.100 up
⚠️
nmcli可管理eth0.100的 IP 地址、DHCP、DNS 等三层参数,但不能设置 PCP 值或修改 VLAN 帧头行为。
使用 tc 设置 802.1p 优先级(软件标记方式)
这是最通用、无需特殊硬件支持的方法,适用于大多数场景:
# 1. 在 VLAN 接口上挂载 HTB qdisc(根队列) sudo tc qdisc add dev eth0.100 root handle 1: htb default 30 # 2. 创建两个类:一个用于高优(PCP=5),一个用于默认(PCP=0) sudo tc class add dev eth0.100 parent 1: classid 1:10 htb rate 100mbit prio 0 sudo tc class add dev eth0.100 parent 1: classid 1:20 htb rate 100mbit prio 1 # 3. 用 iptables 标记语音流量(例如 SIP/ RTP 端口) sudo iptables -t mangle -A POSTROUTING -o eth0.100 -p udp --dport 5060 -j CLASSIFY --set-class 1:10 sudo iptables -t mangle -A POSTROUTING -o eth0.100 -p udp --dport 10000:20000 -j CLASSIFY --set-class 1:10 # 4. 用 tc filter 将标记流量导向对应 class,并设置 VLAN PCP sudo tc filter add dev eth0.100 parent 1: protocol 802.1Q u32 match ip tos 0xe0 0xfc flowid 1:10 action vlan push pcp 5 sudo tc filter add dev eth0.100 parent 1: protocol 802.1Q u32 match ip tos 0x00 0xff flowid 1:20 action vlan push pcp 0
✅ 此方案将 DSCP=224(0xe0,常用于 SIP)或 UDP 大端口范围的出向流量,在打上 VLAN 标签时自动填充 PCP=5;其余走 PCP=0。
? 注意:action vlan push pcp X是tc的高级功能,要求内核 ≥ 4.15 且iproute2≥ 4.19。
(可选)启用硬件 VLAN PCP offload(高性能场景)
若网卡和驱动支持(如 ixgbe、i40e、mlx5),可跳过 tc 软标记,由硬件直接插入 PCP:
# 查看当前 offload 状态 ethtool -k eth0 | grep "vlan" # 启用发送方向的 VLAN 插入与 PCP 设置(需驱动支持) sudo ethtool --offload eth0 tx on rx on sudo ethtool --set-priv-flags eth0 "vlan-ctag-insert" on # 示例,实际命令依驱动而定
? 具体私有 flag 名称需查对应驱动文档(如
mlx5使用eswitch_mode+vlan_insert)。普通千兆网卡(如r8169、e1000e)通常不支持此特性。
验证 PCP 是否生效
-
抓包确认:用
tcpdump在物理口抓包,过滤 VLAN 帧:sudo tcpdump -i eth0 -nn -e 'vlan and port 5060'
观察输出中
vlan 100, p 5字样(p 5表示 PCP=5)。 -
检查
tc规则是否加载:tc filter show dev eth0.100 tc class show dev eth0.100
-
查看
iptablesmangle 表是否命中:sudo iptables -t mangle -L POSTROUTING -v -n
补充说明:为什么 nmcli 不行?
-
nmcli是 NetworkManager 的命令行前端,设计目标是管理 IP 层连接生命周期(地址、路由、DNS、DHCP、认证等); - 它调用的是
libnm,底层不涉及tc、iptables或ethtool这类低层网络控制; - 即使创建了 VLAN 连接(
nmcli con add type vlan ...),它也仅生成ifconfig/ip addr级别配置,不会触碰 qdisc、class 或帧头字段。
所以,要实现 802.1p 精细化分级,必须绕过 nmcli 的限制,组合使用 ip、tc、iptables 和 ethtool。


















