基类

即 mininet.node.Node,
表示一个基本的虚拟网络节点,是所有的网络节点的父类。

实现上其实就是在网络名字空间中的一个shell进程,可以通过各种管道进行通信。该类是模块中其他类的根本,其它类都是直接或间接继承。

节点包括名称、是否在网络名字空间、接口、端口等可能的属性。

init

  1. params: Node parameters (see config() for details)"""
  2. # Make sure class actually works
  3. self.checkSetup()
  4. self.name = name
  5. self.inNamespace = inNamespace
  6. # Stash configuration parameters for future reference
  7. self.params = params
  8. self.intfs = {} # dict of port numbers to interfaces
  9. self.ports = {} # dict of interfaces to port numbers
  10. # replace with Port objects, eventually ?
  11. self.nameToIntf = {} # dict of interface names to Intfs
  12. # Make pylint happy
  13. ( self.shell, self.execed, self.pid, self.stdin, self.stdout,
  14. self.lastPid, self.lastCmd, self.pollOut ) = (
  15. None, None, None, None, None, None, None, None )
  16. self.waiting = False
  17. self.readbuf = ''
  18. # Start command interpreter shell
  19. self.startShell()

初始化函数主要进行参数的初始化,之后通过调用 startShell() 启动一个 shell进程(该进程默认关闭描述符,并从 tty 上分离开来),等待接受传入的命令。句柄被发送给 self.shell 上。

addIntf

  1. def addIntf( self, intf, port=None ):
  2. """Add an interface.
  3. intf: interface
  4. port: port number (optional, typically OpenFlow port number)"""
  5. if port is None:
  6. port = self.newPort()
  7. self.intfs[ port ] = intf
  8. self.ports[ intf ] = port
  9. self.nameToIntf[ intf.name ] = intf
  10. debug( '\n' )
  11. debug( 'added intf %s:%d to node %s\n' % ( intf, port, self.name ) )
  12. if self.inNamespace:
  13. debug( 'moving', intf, 'into namespace for', self.name, '\n' )
  14. moveIntf( intf.name, self )

添加一个接口(比如 <Intf h1-eth0> )到节点上,如果给定了 port(比如 0 ),则建立端口到接口的映射关系。这个映射关系通过 self.intfs 和 self.ports 两个字典来分别维护。

cmd

该函数能在节点所在的进程shell上执行输入的命令。

  1. def cmd( self, *args, **kwargs ):
  2. """Send a command, wait for output, and return it.
  3. cmd: string"""
  4. verbose = kwargs.get( 'verbose', False )
  5. log = info if verbose else debug
  6. log( '*** %s : %s\n' % ( self.name, args ) )
  7. self.sendCmd( *args, **kwargs )
  8. return self.waitOutput( verbose )

config

配置 MAC,IP 或 default Route 信息。

  1. def config( self, mac=None, ip=None,
  2. defaultRoute=None, lo='up', **_params ):
  3. """Configure Node according to (optional) parameters:
  4. mac: MAC address for default interface
  5. ip: IP address for default interface
  6. ifconfig: arbitrary interface configuration
  7. Subclasses should override this method and call
  8. the parent class's config(**params)"""
  9. # If we were overriding this method, we would call
  10. # the superclass config method here as follows:
  11. # r = Parent.config( **_params )
  12. r = {}
  13. self.setParam( r, 'setMAC', mac=mac )
  14. self.setParam( r, 'setIP', ip=ip )
  15. self.setParam( r, 'setDefaultRoute', defaultRoute=defaultRoute )
  16. # This should be examined
  17. self.cmd( 'ifconfig lo ' + lo )
  18. return r

connectionsTo

返回所有从自身连接到给定节点的接口,即 [ intf1, intf2… ]。

  1. def connectionsTo( self, node):
  2. "Return [ intf1, intf2... ] for all intfs that connect self to node."
  3. # We could optimize this if it is important
  4. connections = []
  5. for intf in self.intfList():
  6. link = intf.link
  7. if link:
  8. node1, node2 = link.intf1.node, link.intf2.node
  9. if node1 == self and node2 == node:
  10. connections += [ ( intf, link.intf2 ) ]
  11. elif node1 == node and node2 == self:
  12. connections += [ ( intf, link.intf1 ) ]
  13. return connections