基类
即 mininet.node.Node, 表示一个基本的虚拟网络节点,是所有的网络节点的父类。
实现上其实就是在网络名字空间中的一个shell进程,可以通过各种管道进行通信。该类是模块中其他类的根本,其它类都是直接或间接继承。
节点包括名称、是否在网络名字空间、接口、端口等可能的属性。

init

1
params: Node parameters (see config() for details)"""
2
3
# Make sure class actually works
4
self.checkSetup()
5
6
self.name = name
7
self.inNamespace = inNamespace
8
9
# Stash configuration parameters for future reference
10
self.params = params
11
12
self.intfs = {} # dict of port numbers to interfaces
13
self.ports = {} # dict of interfaces to port numbers
14
# replace with Port objects, eventually ?
15
self.nameToIntf = {} # dict of interface names to Intfs
16
17
# Make pylint happy
18
( self.shell, self.execed, self.pid, self.stdin, self.stdout,
19
self.lastPid, self.lastCmd, self.pollOut ) = (
20
None, None, None, None, None, None, None, None )
21
self.waiting = False
22
self.readbuf = ''
23
24
# Start command interpreter shell
25
self.startShell()
Copied!
初始化函数主要进行参数的初始化,之后通过调用 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 )
Copied!
添加一个接口(比如 <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 )
Copied!

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
Copied!

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
Copied!