
本文详解如何在sdn环境中通过openflow控制器编写精确的流表规则,实现对指定ip(如h4)的访问拦截,同时保障其他主机(h1–h3、h5)间通信畅通,重点补全缺失的包转发逻辑与流表下发机制。
本文详解如何在sdn环境中通过openflow控制器编写精确的流表规则,实现对指定ip(如h4)的访问拦截,同时保障其他主机(h1–h3、h5)间通信畅通,重点补全缺失的包转发逻辑与流表下发机制。
在典型的Mininet + Ryu/POX控制器实验中,仅判断源/目的IP是否匹配黑名单(如h4的IP)是不够的——关键在于后续动作的显式声明。你截图中的 do_final() 方法识别了需拦截的流量(例如 h2 → h4),但未实现“放行其余流量”的转发逻辑,导致合法数据包被静默丢弃,从而中断所有通信。
✅ 正确做法:双路径流表控制
需为每条匹配规则明确指定 OFPActionOutput 输出端口(或 CONTROLLER 交由上层处理),而非依赖默认行为。以下以Ryu控制器为例,展示核心逻辑:
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet, ethernet, ipv4
class SimpleRouter(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(SimpleRouter, self).__init__(*args, **kwargs)
self.blocked_ip = '10.0.0.4' # h4 的 IP
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def packet_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
pkt = packet.Packet(msg.data)
ip_pkt = pkt.get_protocol(ipv4.ipv4)
if not ip_pkt:
return
# 拦截 h2 → h4 流量(示例:源为 h2 且目的为 h4)
if ip_pkt.dst == self.blocked_ip:
# 匹配并丢弃:无 output action 即隐式 drop
match = parser.OFPMatch(eth_type=0x0800, ipv4_dst=self.blocked_ip)
self.add_flow(datapath, 10, match) # 优先级10,无 instructions → DROP
return
# 允许其余IPv4流量:查路由表或基于拓扑泛洪/查L2转发表
# 简化示例:假设交换机已学习MAC,直接泛洪到所有非入端口
out_port = ofproto.OFPP_FLOOD
actions = [parser.OFPActionOutput(out_port)]
match = parser.OFPMatch(eth_type=0x0800)
self.add_flow(datapath, 1, match, actions, idle_timeout=30)
def add_flow(self, datapath, priority, match, actions=None, idle_timeout=0):
actions = actions or []
inst = [datapath.ofproto_parser.OFPInstructionActions(
datapath.ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = datapath.ofproto_parser.OFPFlowMod(
datapath=datapath, priority=priority,
idle_timeout=idle_timeout, hard_timeout=0,
match=match, instructions=inst)
datapath.send_msg(mod)⚠️ 关键注意事项
- 流表优先级必须明确:拦截规则(如 ipv4_dst==10.0.0.4)应设更高优先级(如 priority=10),避免被低优先级泛洪规则覆盖;
- 禁止遗漏 actions:即使允许转发,也必须显式添加 OFPActionOutput(port);空 actions 列表等效于 DROP;
- 避免泛洪滥用:生产环境应结合ARP响应、L3路由计算或使用 ryu.app.rest_router 等模块实现真实三层转发;
- 验证拓扑连通性:运行前确认Mininet中各主机IP正确(h1:10.0.0.1, h2:10.0.0.2, ..., h4:10.0.0.4),并用 pingall 初步测试基础L2连通性。
✅ 验证命令示例
# 启动控制器与Mininet拓扑 $ ryu-manager simple_router.py & $ sudo mn --topo single,4 --controller remote --switch ovsk # 在Mininet CLI中测试 mininet> h1 ping -c 2 h2 # 应成功 mininet> h2 ping -c 2 h4 # 应超时(Request timeout) mininet> h3 ping -c 2 h5 # 应成功
通过补全转发动作、设置合理优先级并严格匹配字段,即可精准实现“阻断特定IP、放行其余流量”的路由器功能。记住:OpenFlow的本质是显式编程——不写动作,即无动作。

















