mininet 中的 n 主机、零开关拓扑的问题

网络工程 专用网 开放流 迷你网
2021-07-12 17:40:24

我正在尝试一些以更好地了解 Mininet 和 Openflow。我已经建立了一个拓扑,在一条线上有 n 台主机,没有交换机。奇怪的是,主机 1 和主机 2 可以互相 ping 通,但其余主机不能。有人能解释一下为什么会这样吗,以及是否有可能让所有节点都能够在不将交换机引入网络的情况下 ping 其邻居?

这是我当前的代码:

#!/usr/bin/python
from mininet.net import Mininet
from utils.FloodlightController import FloodlightController
from mininet.log import setLogLevel
import os,time

if __name__ == '__main__':
    #setLogLevel( 'info' )
    net = Mininet(controller=FloodlightController)
    #net.addController("controller1")

    num_nodes = 8
    for i in range(1,num_nodes):
        net.addHost("h%d"%i)
    for i in range(2,num_nodes):
        net.addLink("h%d"%i, "h%d"%(i-1))

    net.start()
    net.pingAll()
    net.stop()

这是输出:

*** Ping: testing ping reachability
h1 -> h2 X X X X X 
h2 -> h1 X X X X X 
h3 -> X X X X X X 
h4 -> X X X X X X 
h5 -> X X X X X X 
h6 -> X X X X X X 
h7 -> X X X X X X 
*** Results: 95% dropped (2/42 received)
2个回答

也许前两台主机获得了在同一子网中分配的 IP。因此,他们可能通过传统网络进行通信。由于您没有添加开关,因此不应出现循环问题。

您的代码配置错误。控制器对象需要“构建”,只有开关必须“启动”。使用 net.build() 而不是 net.start()。start() 函数用于开关。

基于 Mininet 将主机中的一个接口视为节点的“默认”接口这一事实,这里有两个问题。

  1. 在有很多接口的主机中,mininet只给默认接口分配一个IP,所以你必须用一个连贯的IP计划来分配IP。 有关详细信息,请参见此处。

    您可以在以下代码中看到,您可以得到不同的结果,仅更改添加链接的顺序(添加链接时,还会创建接口,如果新接口是主机中的第一个,它将是“默认”,因此具有 IP):

    #!/usr/bin/python
    
    from mininet.net import Mininet
    from mininet.log import setLogLevel
    import os,time
    
    if __name__ == '__main__':
        #setLogLevel( 'info' )
        net = Mininet()
    
        num_nodes = 8
        hosts=[None] * num_nodes
    
        for i in range(1,num_nodes):
            hosts[i]=net.addHost("h%d"%i)
        for i in range(2,num_nodes,2):
            net.addLink(hosts[i], hosts[i-1])
        for i in range(3,num_nodes,2):
            net.addLink(hosts[i], hosts[i-1])
    
        net.start()
        net.pingAll()
        net.stop()
    

这是输出:

    h1 -> h2 X X X X X 
    h2 -> h1 X X X X X 
    h3 -> X X h4 X X X 
    h4 -> X X h3 X X X 
    h5 -> X X X X h6 X 
    h6 -> X X X X h5 X 
    h7 -> X X X X X X 
  1. pingAll() 尝试从每个主机 ping 到任何其他主机的默认接口的 IP。仅当您以这种方式在每个主机中启用 ip 转发时,这才有效:

    host.cmd('sysctl -w net.ipv4.ip_forward=1')
    

    否则,您必须 ping 每个主机的邻居并提供正确的 IP。

在这里,您可以找到可以将 IP 分配给接口并 ping 每个节点的所有邻居的代码。

#!/usr/bin/python

from mininet.net import Mininet
from mininet.log import output

if __name__ == '__main__':

    net = Mininet()

    num_nodes = 8 

    # from 1 to num_nodes
    for i in range(1,num_nodes+1): 
        net.addHost('h%d'%i,ip=None)

    # from 1 to num_nodes-1 because the index starts from zero
    for i in range(1,num_nodes): 

        h1 = net.hosts[i-1]
        h2 = net.hosts[i]

        net.addLink(h2, h1, intfName1 = '%s-eth0'%h2.name, intfName2 = '%s-eth1'%h1.name)
        h2.intf('%s-eth0'%h2.name).setIP('10.0.%d.1'%i, 24) 
        h1.intf('%s-eth1'%h1.name).setIP('10.0.%d.2'%i, 24) 

    net.start()

    # Ping forward and backward nodes
    for i in range(0,num_nodes):
        node = net.hosts[i]

        fwdNode, bwNode = None, None

        output('%s -> '%node.name)

        if i!=0:
            bwNode = net.hosts[i-1]
            bwIP = bwNode.IP('%s-eth1'%bwNode.name)
            result = node.cmd('ping -c1 %s'%bwIP)
            sent, received = net._parsePing(result)

            output(('%s '%bwNode.name) if received else 'X ')

        if i!=7:
            fwdNode = net.hosts[i+1]
            fwdIP = fwdNode.IP('%s-eth0'%fwdNode.name)
            result = node.cmd('ping -c1 %s'%fwdIP)
            sent, received = net._parsePing(result)

            output(('%s '%fwdNode.name) if received else 'X ')

        output('\n')

    net.stop()

这是输出:

h1 -> h2 
h2 -> h1 h3 
h3 -> h2 h4 
h4 -> h3 h5 
h5 -> h4 h6 
h6 -> h5 h7 
h7 -> h6 h8 
h8 -> h7