首页 文章

设置ICMP与POX控制器匹配

提问于
浏览
3

我正在尝试使用POX控制器向交换机添加流条目,我的代码是:

fm = of.ofp_flow_mod()
    fm.match.in_port = 1
    fm.priority = 33001
    fm.match.dl_type = 0x800
    fm.match.nw_src = IPAddr("10.0.0.1")
    fm.match.nw_dst = IPAddr("10.0.0.5")

    fm.actions.append(of.ofp_action_output( port = 2 ) )
    event.connection.send( fm )

但是,当我从10.0.0.1 ping到10.0.0.5时,没有回复 . 可能是什么问题? (我还为ICMP回复添加了对称流)

谢谢

1 回答

  • 4

    (注意:我在以下示例中将 10.0.0.5 更改为 10.0.0.3 ,因为我使用1个交换机测试,mininet中有3个主机拓扑 . )

    您的问题是ARP请求无法通过 . 您需要添加两个额外的规则来让dl_type = 0x0806的消息通过 . 所以:

    def _handle_ConnectionUp (event):
      fm = of.ofp_flow_mod()
      fm.match.in_port = 1
      fm.priority = 33001
      fm.match.dl_type = 0x0800
      fm.match.nw_src = IPAddr("10.0.0.1")
      fm.match.nw_dst = IPAddr("10.0.0.3")
      fm.actions.append(of.ofp_action_output( port = 3 ) )
      event.connection.send( fm )
    
      fm = of.ofp_flow_mod()
      fm.match.in_port = 3
      fm.priority = 33001
      fm.match.dl_type = 0x0800
      fm.match.nw_src = IPAddr("10.0.0.3")
      fm.match.nw_dst = IPAddr("10.0.0.1")
      fm.actions.append(of.ofp_action_output( port = 1 ) )
      event.connection.send( fm )
    
      fm = of.ofp_flow_mod()
      fm.match.in_port = 1
      fm.priority = 33001
      fm.match.dl_type = 0x0806
      fm.actions.append(of.ofp_action_output( port = 3 ) )
      event.connection.send( fm )
    
      fm = of.ofp_flow_mod()
      fm.match.in_port = 3
      fm.priority = 33001
      fm.match.dl_type = 0x0806
      fm.actions.append(of.ofp_action_output( port = 1 ) )
      event.connection.send( fm )
    

    如果您的网络中没有任何环路,您还可以添加一个规则,在每个端口上泛洪数据包,除了它来自的端口 .

    fm = of.ofp_flow_mod()
      fm.priority = 33001
      fm.match.dl_type = 0x0806
      fm.actions.append(of.ofp_action_output( port = of.OFPP_FLOOD ) )
      event.connection.send( fm )
    

    更多信息:当您发送发往IP地址的ICMP回应请求时,会发生以下情况:

    • 主机发出ARP请求("who has IP 10.0.0.3?")以找出下一跳的硬件MAC地址 .

    • 然后主机向下一跳发送ICMP数据包 .

    如果初始查询没有响应,则不会发送ICMP数据包,因为主机不知道接下来要将其发送到何处 . 您可以在本答案末尾的 tcpdump 示例中看到此信息 .

    这是mininet的输出:

    mininet@mininet-vm:~$ sudo mn --topo single,3 --mac --switch ovsk,protocols=OpenFlow10 --controller remote
    *** Creating network
    *** Adding controller
    *** Adding hosts:
    h1 h2 h3 
    *** Adding switches:
    s1 
    *** Adding links:
    (h1, s1) (h2, s1) (h3, s1) 
    *** Configuring hosts
    h1 h2 h3 
    *** Starting controller
    c0 
    *** Starting 1 switches
    s1 ...
    *** Starting CLI:
    mininet> pingall
    *** Ping: testing ping reachability
    h1 -> X h3 
    h2 -> X X 
    h3 -> h1 X 
    *** Results: 66% dropped (2/6 received)
    mininet>
    

    那么,如果我们已经"know"下一跳是什么呢?在这种情况下,我们可以告诉 ping 将ICMP IPv4数据包发送出特定接口 . 它不会使用ARP . 但是,ping请求的接收方仍将尝试使用ARP来确定如何发送响应 . 请求将到达,但响应不会 .

    您可以通过运行以下命令将初始ping强制发送到特定接口,而不使用ARP请求:

    # Run this on host h1
    h1 ping -I h1-eth0 -c1 10.0.0.3
    

    即使您没有设置ARP规则(因为 nw_srcnw_dst 匹配),初始ICMP数据包也将通过 . 如果在h3上运行 tcpdump (运行 xterm h3 并在新终端 tcpdump 中),则可以看到ICMP消息在这种情况下到达,但返回消息没有 .

    # Run this on host h3
    root@mininet-vm:~# tcpdump
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on h3-eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    20:20:19.428465 IP 10.0.0.1 > 10.0.0.3: ICMP echo request, id 24690, seq 1, length 64
    20:20:19.428481 ARP, Request who-has 10.0.0.1 tell 10.0.0.3, length 28
    20:20:20.428094 ARP, Request who-has 10.0.0.1 tell 10.0.0.3, length 28
    20:20:21.428097 ARP, Request who-has 10.0.0.1 tell 10.0.0.3, length 28
    

    最后的ARP请求的长序列是接收主机试图找出应该将响应发送回哪个接口 .

相关问题