updated ctrlnets to assign unique addresses per server, fixed ovs command issue for interface specific commands
This commit is contained in:
parent
0b8bc7bd13
commit
61a4e228a1
6 changed files with 81 additions and 79 deletions
|
@ -4,12 +4,9 @@ Defines the base logic for nodes used within core.
|
|||
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import socket
|
||||
import string
|
||||
import threading
|
||||
from builtins import range
|
||||
from socket import AF_INET, AF_INET6
|
||||
|
||||
from core import utils
|
||||
|
@ -18,8 +15,8 @@ from core.emulator.data import LinkData, NodeData
|
|||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.errors import CoreCommandError
|
||||
from core.nodes import client, ipaddress
|
||||
from core.nodes.interface import CoreInterface, TunTap, Veth
|
||||
from core.nodes.netclient import LinuxNetClient, OvsNetClient
|
||||
from core.nodes.interface import TunTap, Veth
|
||||
from core.nodes.netclient import get_net_client
|
||||
|
||||
_DEFAULT_MTU = 1500
|
||||
|
||||
|
@ -63,10 +60,8 @@ class NodeBase(object):
|
|||
self.opaque = None
|
||||
self.position = Position()
|
||||
|
||||
if session.options.get_config("ovs") == "True":
|
||||
self.net_client = OvsNetClient(self.net_cmd)
|
||||
else:
|
||||
self.net_client = LinuxNetClient(self.net_cmd)
|
||||
use_ovs = session.options.get_config("ovs") == "True"
|
||||
self.net_client = get_net_client(use_ovs, self.net_cmd)
|
||||
|
||||
def startup(self):
|
||||
"""
|
||||
|
@ -461,15 +456,13 @@ class CoreNode(CoreNodeBase):
|
|||
|
||||
def create_node_net_client(self, use_ovs):
|
||||
"""
|
||||
Create a client for running network orchestration commands.
|
||||
Create node network client for running network commands within the nodes
|
||||
container.
|
||||
|
||||
:param bool use_ovs: True to use OVS bridges, False for Linux bridge
|
||||
:return: network client
|
||||
:param bool use_ovs: True for OVS bridges, False for Linux bridges
|
||||
:return:node network client
|
||||
"""
|
||||
if use_ovs:
|
||||
return OvsNetClient(self.node_net_cmd)
|
||||
else:
|
||||
return LinuxNetClient(self.node_net_cmd)
|
||||
return get_net_client(use_ovs, self.node_net_cmd)
|
||||
|
||||
def alive(self):
|
||||
"""
|
||||
|
@ -675,11 +668,7 @@ class CoreNode(CoreNodeBase):
|
|||
raise ValueError("interface name (%s) too long" % name)
|
||||
|
||||
veth = Veth(
|
||||
node=self,
|
||||
name=name,
|
||||
localname=localname,
|
||||
start=self.up,
|
||||
server=self.server,
|
||||
self.session, self, name, localname, start=self.up, server=self.server
|
||||
)
|
||||
|
||||
if self.up:
|
||||
|
@ -732,7 +721,7 @@ class CoreNode(CoreNodeBase):
|
|||
sessionid = self.session.short_session_id()
|
||||
localname = "tap%s.%s.%s" % (self.id, ifindex, sessionid)
|
||||
name = ifname
|
||||
tuntap = TunTap(node=self, name=name, localname=localname, start=self.up)
|
||||
tuntap = TunTap(self.session, self, name, localname, start=self.up)
|
||||
|
||||
try:
|
||||
self.addnetif(tuntap, ifindex)
|
||||
|
@ -849,35 +838,6 @@ class CoreNode(CoreNodeBase):
|
|||
self.ifup(ifindex)
|
||||
return ifindex
|
||||
|
||||
def connectnode(self, ifname, othernode, otherifname):
|
||||
"""
|
||||
Connect a node.
|
||||
|
||||
:param str ifname: name of interface to connect
|
||||
:param core.nodes.base.CoreNode othernode: node to connect to
|
||||
:param str otherifname: interface name to connect to
|
||||
:return: nothing
|
||||
"""
|
||||
tmplen = 8
|
||||
tmp1 = "tmp." + "".join(
|
||||
[random.choice(string.ascii_lowercase) for _ in range(tmplen)]
|
||||
)
|
||||
tmp2 = "tmp." + "".join(
|
||||
[random.choice(string.ascii_lowercase) for _ in range(tmplen)]
|
||||
)
|
||||
self.net_client.create_veth(tmp1, tmp2)
|
||||
self.net_client.device_ns(tmp1, str(self.pid))
|
||||
self.node_net_client.device_name(tmp1, ifname)
|
||||
interface = CoreInterface(node=self, name=ifname, mtu=_DEFAULT_MTU)
|
||||
self.addnetif(interface, self.newifindex())
|
||||
|
||||
self.net_client.device_ns(tmp2, str(othernode.pid))
|
||||
othernode.node_net_client.device_name(tmp2, otherifname)
|
||||
other_interface = CoreInterface(
|
||||
node=othernode, name=otherifname, mtu=_DEFAULT_MTU
|
||||
)
|
||||
othernode.addnetif(other_interface, othernode.newifindex())
|
||||
|
||||
def addfile(self, srcname, filename):
|
||||
"""
|
||||
Add a file.
|
||||
|
|
|
@ -7,7 +7,7 @@ from core import utils
|
|||
from core.emulator.enumerations import NodeTypes
|
||||
from core.errors import CoreCommandError
|
||||
from core.nodes.base import CoreNode
|
||||
from core.nodes.netclient import LinuxNetClient, OvsNetClient
|
||||
from core.nodes.netclient import get_net_client
|
||||
|
||||
|
||||
class DockerClient(object):
|
||||
|
@ -107,10 +107,14 @@ class DockerNode(CoreNode):
|
|||
super(DockerNode, self).__init__(session, _id, name, nodedir, bootsh, start)
|
||||
|
||||
def create_node_net_client(self, use_ovs):
|
||||
if use_ovs:
|
||||
return OvsNetClient(self.nsenter_cmd)
|
||||
else:
|
||||
return LinuxNetClient(self.nsenter_cmd)
|
||||
"""
|
||||
Create node network client for running network commands within the nodes
|
||||
container.
|
||||
|
||||
:param bool use_ovs: True for OVS bridges, False for Linux bridges
|
||||
:return:node network client
|
||||
"""
|
||||
return get_net_client(use_ovs, self.nsenter_cmd)
|
||||
|
||||
def alive(self):
|
||||
"""
|
||||
|
|
|
@ -8,7 +8,7 @@ from builtins import int, range
|
|||
|
||||
from core import utils
|
||||
from core.errors import CoreCommandError
|
||||
from core.nodes.netclient import LinuxNetClient
|
||||
from core.nodes.netclient import get_net_client
|
||||
|
||||
|
||||
class CoreInterface(object):
|
||||
|
@ -16,17 +16,18 @@ class CoreInterface(object):
|
|||
Base class for network interfaces.
|
||||
"""
|
||||
|
||||
def __init__(self, node, name, mtu, server=None):
|
||||
def __init__(self, session, node, name, mtu, server=None):
|
||||
"""
|
||||
Creates a PyCoreNetIf instance.
|
||||
|
||||
:param core.emulator.session.Session session: core session instance
|
||||
:param core.nodes.base.CoreNode node: node for interface
|
||||
:param str name: interface name
|
||||
:param mtu: mtu value
|
||||
:param int mtu: mtu value
|
||||
:param core.emulator.distributed.DistributedServer server: remote server node
|
||||
will run on, default is None for localhost
|
||||
"""
|
||||
|
||||
self.session = session
|
||||
self.node = node
|
||||
self.name = name
|
||||
if not isinstance(mtu, int):
|
||||
|
@ -45,7 +46,8 @@ class CoreInterface(object):
|
|||
# index used to find flow data
|
||||
self.flow_id = None
|
||||
self.server = server
|
||||
self.net_client = LinuxNetClient(self.net_cmd)
|
||||
use_ovs = session.options.get_config("ovs") == "True"
|
||||
self.net_client = get_net_client(use_ovs, self.net_cmd)
|
||||
|
||||
def net_cmd(self, args, env=None, cwd=None, wait=True):
|
||||
"""
|
||||
|
@ -211,21 +213,24 @@ class Veth(CoreInterface):
|
|||
Provides virtual ethernet functionality for core nodes.
|
||||
"""
|
||||
|
||||
def __init__(self, node, name, localname, mtu=1500, server=None, start=True):
|
||||
def __init__(
|
||||
self, session, node, name, localname, mtu=1500, server=None, start=True
|
||||
):
|
||||
"""
|
||||
Creates a VEth instance.
|
||||
|
||||
:param core.emulator.session.Session session: core session instance
|
||||
:param core.nodes.base.CoreNode node: related core node
|
||||
:param str name: interface name
|
||||
:param str localname: interface local name
|
||||
:param mtu: interface mtu
|
||||
:param int mtu: interface mtu
|
||||
:param core.emulator.distributed.DistributedServer server: remote server node
|
||||
will run on, default is None for localhost
|
||||
:param bool start: start flag
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
"""
|
||||
# note that net arg is ignored
|
||||
CoreInterface.__init__(self, node, name, mtu, server)
|
||||
CoreInterface.__init__(self, session, node, name, mtu, server)
|
||||
self.localname = localname
|
||||
self.up = False
|
||||
if start:
|
||||
|
@ -271,19 +276,22 @@ class TunTap(CoreInterface):
|
|||
TUN/TAP virtual device in TAP mode
|
||||
"""
|
||||
|
||||
def __init__(self, node, name, localname, mtu=1500, server=None, start=True):
|
||||
def __init__(
|
||||
self, session, node, name, localname, mtu=1500, server=None, start=True
|
||||
):
|
||||
"""
|
||||
Create a TunTap instance.
|
||||
|
||||
:param core.emulator.session.Session session: core session instance
|
||||
:param core.nodes.base.CoreNode node: related core node
|
||||
:param str name: interface name
|
||||
:param str localname: local interface name
|
||||
:param mtu: interface mtu
|
||||
:param int mtu: interface mtu
|
||||
:param core.emulator.distributed.DistributedServer server: remote server node
|
||||
will run on, default is None for localhost
|
||||
:param bool start: start flag
|
||||
"""
|
||||
CoreInterface.__init__(self, node, name, mtu, server)
|
||||
CoreInterface.__init__(self, session, node, name, mtu, server)
|
||||
self.localname = localname
|
||||
self.up = False
|
||||
self.transport_type = "virtual"
|
||||
|
@ -466,8 +474,7 @@ class GreTap(CoreInterface):
|
|||
will run on, default is None for localhost
|
||||
:raises CoreCommandError: when there is a command exception
|
||||
"""
|
||||
CoreInterface.__init__(self, node, name, mtu, server)
|
||||
self.session = session
|
||||
CoreInterface.__init__(self, session, node, name, mtu, server)
|
||||
if _id is None:
|
||||
# from PyCoreObj
|
||||
_id = ((id(self) >> 16) ^ (id(self) & 0xFFFF)) & 0xFFFF
|
||||
|
|
|
@ -7,6 +7,20 @@ import os
|
|||
from core.constants import BRCTL_BIN, ETHTOOL_BIN, IP_BIN, OVS_BIN, TC_BIN
|
||||
|
||||
|
||||
def get_net_client(use_ovs, run):
|
||||
"""
|
||||
Retrieve desired net client for running network commands.
|
||||
|
||||
:param bool use_ovs: True for OVS bridges, False for Linux bridges
|
||||
:param func run: function used to run net client commands
|
||||
:return: net client class
|
||||
"""
|
||||
if use_ovs:
|
||||
return OvsNetClient(run)
|
||||
else:
|
||||
return LinuxNetClient(run)
|
||||
|
||||
|
||||
class LinuxNetClient(object):
|
||||
"""
|
||||
Client for creating Linux bridges and ip interfaces for nodes.
|
||||
|
|
|
@ -16,6 +16,7 @@ from core.errors import CoreCommandError, CoreError
|
|||
from core.nodes import ipaddress
|
||||
from core.nodes.base import CoreNetworkBase
|
||||
from core.nodes.interface import GreTap, Veth
|
||||
from core.nodes.netclient import get_net_client
|
||||
|
||||
ebtables_lock = threading.Lock()
|
||||
|
||||
|
@ -558,7 +559,7 @@ class CoreNetwork(CoreNetworkBase):
|
|||
if len(name) >= 16:
|
||||
raise ValueError("interface name %s too long" % name)
|
||||
|
||||
netif = Veth(node=None, name=name, localname=localname, mtu=1500, start=self.up)
|
||||
netif = Veth(self.session, None, name, localname, start=self.up)
|
||||
self.attach(netif)
|
||||
if net.up:
|
||||
# this is similar to net.attach() but uses netif.name instead of localname
|
||||
|
@ -766,6 +767,24 @@ class CtrlNet(CoreNetwork):
|
|||
self.serverintf = serverintf
|
||||
CoreNetwork.__init__(self, session, _id, name, start, server)
|
||||
|
||||
def add_addresses(self, address):
|
||||
"""
|
||||
Add addresses used for created control networks,
|
||||
|
||||
:param core.nodes.interfaces.IpAddress address: starting address to use
|
||||
:return:
|
||||
"""
|
||||
use_ovs = self.session.options.get_config("ovs") == "True"
|
||||
current = "%s/%s" % (address, self.prefix.prefixlen)
|
||||
net_client = get_net_client(use_ovs, utils.check_cmd)
|
||||
net_client.create_address(self.brname, current)
|
||||
for name in self.session.servers:
|
||||
server = self.session.servers[name]
|
||||
address -= 1
|
||||
current = "%s/%s" % (address, self.prefix.prefixlen)
|
||||
net_client = get_net_client(use_ovs, server.remote_cmd)
|
||||
net_client.create_address(self.brname, current)
|
||||
|
||||
def startup(self):
|
||||
"""
|
||||
Startup functionality for the control network.
|
||||
|
@ -778,16 +797,14 @@ class CtrlNet(CoreNetwork):
|
|||
|
||||
CoreNetwork.startup(self)
|
||||
|
||||
if self.hostid:
|
||||
addr = self.prefix.addr(self.hostid)
|
||||
else:
|
||||
addr = self.prefix.max_addr()
|
||||
|
||||
logging.info("added control network bridge: %s %s", self.brname, self.prefix)
|
||||
|
||||
if self.assign_address:
|
||||
addrlist = ["%s/%s" % (addr, self.prefix.prefixlen)]
|
||||
self.addrconfig(addrlist=addrlist)
|
||||
if self.hostid and self.assign_address:
|
||||
address = self.prefix.addr(self.hostid)
|
||||
self.add_addresses(address)
|
||||
elif self.assign_address:
|
||||
address = self.prefix.max_addr()
|
||||
self.add_addresses(address)
|
||||
|
||||
if self.updown_script:
|
||||
logging.info(
|
||||
|
|
|
@ -246,7 +246,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
|||
will run on, default is None for localhost
|
||||
"""
|
||||
CoreNodeBase.__init__(self, session, _id, name, start, server)
|
||||
CoreInterface.__init__(self, node=self, name=name, mtu=mtu)
|
||||
CoreInterface.__init__(self, session, self, name, mtu, server)
|
||||
self.up = False
|
||||
self.lock = threading.RLock()
|
||||
self.ifindex = None
|
||||
|
|
Loading…
Reference in a new issue