daemon: CoreNetworkBase.linkconfig now takes a LinkOptions object, removed usage of emudata.link_config

This commit is contained in:
Blake Harnden 2020-06-09 13:41:31 -07:00
parent 3be15a1316
commit 2965273f58
9 changed files with 53 additions and 127 deletions

View file

@ -11,6 +11,7 @@ from lxml import etree
from core.config import ConfigGroup, Configuration from core.config import ConfigGroup, Configuration
from core.emane import emanemanifest, emanemodel from core.emane import emanemanifest, emanemodel
from core.emane.nodes import EmaneNet from core.emane.nodes import EmaneNet
from core.emulator.emudata import LinkOptions
from core.emulator.enumerations import TransportType from core.emulator.enumerations import TransportType
from core.nodes.interface import CoreInterface from core.nodes.interface import CoreInterface
from core.xml import emanexml from core.xml import emanexml
@ -114,14 +115,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
emanexml.create_file(shim_element, "shim", shim_file) emanexml.create_file(shim_element, "shim", shim_file)
def linkconfig( def linkconfig(
self, self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
netif: CoreInterface,
bw: float = None,
delay: float = None,
loss: float = None,
duplicate: float = None,
jitter: float = None,
netif2: CoreInterface = None,
) -> None: ) -> None:
""" """
Generate CommEffect events when a Link Message is received having Generate CommEffect events when a Link Message is received having
@ -142,15 +136,14 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
emane_node = self.session.get_node(self.id, EmaneNet) emane_node = self.session.get_node(self.id, EmaneNet)
nemid = emane_node.getnemid(netif) nemid = emane_node.getnemid(netif)
nemid2 = emane_node.getnemid(netif2) nemid2 = emane_node.getnemid(netif2)
mbw = bw
logging.info("sending comm effect event") logging.info("sending comm effect event")
event.append( event.append(
nemid, nemid,
latency=convert_none(delay), latency=convert_none(options.delay),
jitter=convert_none(jitter), jitter=convert_none(options.jitter),
loss=convert_none(loss), loss=convert_none(options.per),
duplicate=convert_none(duplicate), duplicate=convert_none(options.dup),
unicast=int(convert_none(bw)), unicast=int(convert_none(options.bandwidth)),
broadcast=int(convert_none(mbw)), broadcast=int(convert_none(options.bandwidth)),
) )
service.publish(nemid2, event) service.publish(nemid2, event)

View file

@ -8,6 +8,7 @@ from typing import Dict, List
from core.config import ConfigGroup, Configuration from core.config import ConfigGroup, Configuration
from core.emane import emanemanifest from core.emane import emanemanifest
from core.emane.nodes import EmaneNet from core.emane.nodes import EmaneNet
from core.emulator.emudata import LinkOptions
from core.emulator.enumerations import ConfigDataTypes, TransportType from core.emulator.enumerations import ConfigDataTypes, TransportType
from core.errors import CoreError from core.errors import CoreError
from core.location.mobility import WirelessModel from core.location.mobility import WirelessModel
@ -155,24 +156,13 @@ class EmaneModel(WirelessModel):
logging.exception("error during update") logging.exception("error during update")
def linkconfig( def linkconfig(
self, self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
netif: CoreInterface,
bw: float = None,
delay: float = None,
loss: float = None,
duplicate: float = None,
jitter: float = None,
netif2: CoreInterface = None,
) -> None: ) -> None:
""" """
Invoked when a Link Message is received. Default is unimplemented. Invoked when a Link Message is received. Default is unimplemented.
:param netif: interface one :param netif: interface one
:param bw: bandwidth to set to :param options: options for configuring link
:param delay: packet delay to set to
:param loss: packet loss to set to
:param duplicate: duplicate percentage to set to
:param jitter: jitter to set to
:param netif2: interface two :param netif2: interface two
:return: nothing :return: nothing
""" """

View file

@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
from core.emulator.data import LinkData from core.emulator.data import LinkData
from core.emulator.distributed import DistributedServer from core.emulator.distributed import DistributedServer
from core.emulator.emudata import LinkOptions
from core.emulator.enumerations import ( from core.emulator.enumerations import (
LinkTypes, LinkTypes,
MessageFlags, MessageFlags,
@ -60,21 +61,14 @@ class EmaneNet(CoreNetworkBase):
self.mobility = None self.mobility = None
def linkconfig( def linkconfig(
self, self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
netif: CoreInterface,
bw: float = None,
delay: float = None,
loss: float = None,
duplicate: float = None,
jitter: float = None,
netif2: CoreInterface = None,
) -> None: ) -> None:
""" """
The CommEffect model supports link configuration. The CommEffect model supports link configuration.
""" """
if not self.model: if not self.model:
return return
self.model.linkconfig(netif, bw, delay, loss, duplicate, jitter, netif2) self.model.linkconfig(netif, options, netif2)
def config(self, conf: str) -> None: def config(self, conf: str) -> None:
self.conf = conf self.conf = conf

View file

@ -1,44 +1,13 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import TYPE_CHECKING, List, Optional, Union from typing import TYPE_CHECKING, List, Optional
import netaddr import netaddr
from core import utils from core import utils
from core.api.grpc.core_pb2 import LinkOptions
from core.emulator.enumerations import LinkTypes from core.emulator.enumerations import LinkTypes
from core.nodes.interface import CoreInterface
if TYPE_CHECKING: if TYPE_CHECKING:
from core.nodes.base import CoreNetworkBase, CoreNode from core.nodes.base import CoreNode
from core.nodes.physical import PhysicalNode
LinkConfigNode = Union[CoreNetworkBase, PhysicalNode]
def link_config(
node: "LinkConfigNode",
interface: CoreInterface,
link_options: LinkOptions,
interface_two: CoreInterface = None,
) -> None:
"""
Convenience method for configuring a link,
:param node: network to configure link for
:param interface: interface to configure
:param link_options: data to configure link with
:param interface_two: other interface associated, default is None
:return: nothing
"""
node.linkconfig(
interface,
link_options.bandwidth,
link_options.delay,
link_options.per,
link_options.dup,
link_options.jitter,
interface_two,
)
@dataclass @dataclass

View file

@ -19,7 +19,7 @@ from core.emane.emanemanager import EmaneManager
from core.emane.nodes import EmaneNet from core.emane.nodes import EmaneNet
from core.emulator.data import ConfigData, EventData, ExceptionData, FileData, LinkData from core.emulator.data import ConfigData, EventData, ExceptionData, FileData, LinkData
from core.emulator.distributed import DistributedController from core.emulator.distributed import DistributedController
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions, link_config from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
from core.emulator.enumerations import ( from core.emulator.enumerations import (
EventTypes, EventTypes,
ExceptionLevels, ExceptionLevels,
@ -358,7 +358,7 @@ class Session:
node_one_interface = node_one.netif(ifindex) node_one_interface = node_one.netif(ifindex)
wireless_net = isinstance(net_one, (EmaneNet, WlanNode)) wireless_net = isinstance(net_one, (EmaneNet, WlanNode))
if not wireless_net: if not wireless_net:
link_config(net_one, node_one_interface, link_options) net_one.linkconfig(node_one_interface, link_options)
# network to node # network to node
if node_two and net_one: if node_two and net_one:
@ -371,7 +371,7 @@ class Session:
node_two_interface = node_two.netif(ifindex) node_two_interface = node_two.netif(ifindex)
wireless_net = isinstance(net_one, (EmaneNet, WlanNode)) wireless_net = isinstance(net_one, (EmaneNet, WlanNode))
if not link_options.unidirectional and not wireless_net: if not link_options.unidirectional and not wireless_net:
link_config(net_one, node_two_interface, link_options) net_one.linkconfig(node_two_interface, link_options)
# network to network # network to network
if net_one and net_two: if net_one and net_two:
@ -382,18 +382,16 @@ class Session:
) )
interface = net_one.linknet(net_two) interface = net_one.linknet(net_two)
node_one_interface = interface node_one_interface = interface
link_config(net_one, interface, link_options) net_one.linkconfig(interface, link_options)
if not link_options.unidirectional: if not link_options.unidirectional:
interface.swapparams("_params_up") interface.swapparams("_params_up")
link_config(net_two, interface, link_options) net_two.linkconfig(interface, link_options)
interface.swapparams("_params_up") interface.swapparams("_params_up")
# a tunnel node was found for the nodes # a tunnel node was found for the nodes
addresses = [] addresses = []
if not node_one and all([net_one, interface_one]): if not node_one and all([net_one, interface_one]):
addresses.extend(interface_one.get_addresses()) addresses.extend(interface_one.get_addresses())
if not node_two and all([net_two, interface_two]): if not node_two and all([net_two, interface_two]):
addresses.extend(interface_two.get_addresses()) addresses.extend(interface_two.get_addresses())
@ -418,14 +416,14 @@ class Session:
node_one.adoptnetif( node_one.adoptnetif(
tunnel, interface_one.id, interface_one.mac, addresses tunnel, interface_one.id, interface_one.mac, addresses
) )
link_config(node_one, tunnel, link_options) node_one.linkconfig(tunnel, link_options)
elif node_two and isinstance(node_two, PhysicalNode): elif node_two and isinstance(node_two, PhysicalNode):
logging.info("adding link for physical node: %s", node_two.name) logging.info("adding link for physical node: %s", node_two.name)
addresses = interface_two.get_addresses() addresses = interface_two.get_addresses()
node_two.adoptnetif( node_two.adoptnetif(
tunnel, interface_two.id, interface_two.mac, addresses tunnel, interface_two.id, interface_two.mac, addresses
) )
link_config(node_two, tunnel, link_options) node_two.linkconfig(tunnel, link_options)
finally: finally:
if node_one: if node_one:
node_one.lock.release() node_one.lock.release()
@ -596,28 +594,28 @@ class Session:
if upstream: if upstream:
interface.swapparams("_params_up") interface.swapparams("_params_up")
link_config(net_one, interface, link_options) net_one.linkconfig(interface, link_options)
interface.swapparams("_params_up") interface.swapparams("_params_up")
else: else:
link_config(net_one, interface, link_options) net_one.linkconfig(interface, link_options)
if not link_options.unidirectional: if not link_options.unidirectional:
if upstream: if upstream:
link_config(net_two, interface, link_options) net_two.linkconfig(interface, link_options)
else: else:
interface.swapparams("_params_up") interface.swapparams("_params_up")
link_config(net_two, interface, link_options) net_two.linkconfig(interface, link_options)
interface.swapparams("_params_up") interface.swapparams("_params_up")
else: else:
raise CoreError("modify link for unknown nodes") raise CoreError("modify link for unknown nodes")
elif not node_one: elif not node_one:
# node1 = layer 2node, node2 = layer3 node # node1 = layer 2node, node2 = layer3 node
interface = node_two.netif(interface_two_id) interface = node_two.netif(interface_two_id)
link_config(net_one, interface, link_options) net_one.linkconfig(interface, link_options)
elif not node_two: elif not node_two:
# node2 = layer 2node, node1 = layer3 node # node2 = layer 2node, node1 = layer3 node
interface = node_one.netif(interface_one_id) interface = node_one.netif(interface_one_id)
link_config(net_one, interface, link_options) net_one.linkconfig(interface, link_options)
else: else:
common_networks = node_one.commonnets(node_two) common_networks = node_one.commonnets(node_two)
if not common_networks: if not common_networks:
@ -630,10 +628,10 @@ class Session:
): ):
continue continue
link_config(net_one, interface_one, link_options, interface_two) net_one.linkconfig(interface_one, link_options, interface_two)
if not link_options.unidirectional: if not link_options.unidirectional:
link_config( net_one.linkconfig(
net_one, interface_two, link_options, interface_one interface_two, link_options, interface_one
) )
finally: finally:
if node_one: if node_one:

View file

@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Dict, List, Tuple
from core import utils from core import utils
from core.config import ConfigGroup, ConfigurableOptions, Configuration, ModelManager from core.config import ConfigGroup, ConfigurableOptions, Configuration, ModelManager
from core.emulator.data import EventData, LinkData from core.emulator.data import EventData, LinkData
from core.emulator.emudata import LinkOptions
from core.emulator.enumerations import ( from core.emulator.enumerations import (
ConfigDataTypes, ConfigDataTypes,
EventTypes, EventTypes,
@ -334,9 +335,13 @@ class BasicRangeModel(WirelessModel):
""" """
with self._netifslock: with self._netifslock:
for netif in self._netifs: for netif in self._netifs:
self.wlan.linkconfig( options = LinkOptions(
netif, self.bw, self.delay, self.loss, jitter=self.jitter bandwidth=self.bw,
delay=self.delay,
per=self.loss,
jitter=self.jitter,
) )
self.wlan.linkconfig(netif, options)
def get_position(self, netif: CoreInterface) -> Tuple[float, float, float]: def get_position(self, netif: CoreInterface) -> Tuple[float, float, float]:
""" """

View file

@ -15,7 +15,7 @@ from core import utils
from core.configservice.dependencies import ConfigServiceDependencies from core.configservice.dependencies import ConfigServiceDependencies
from core.constants import MOUNT_BIN, VNODED_BIN from core.constants import MOUNT_BIN, VNODED_BIN
from core.emulator.data import LinkData, NodeData from core.emulator.data import LinkData, NodeData
from core.emulator.emudata import InterfaceData from core.emulator.emudata import InterfaceData, LinkOptions
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
from core.errors import CoreCommandError, CoreError from core.errors import CoreCommandError, CoreError
from core.nodes.client import VnodeClient from core.nodes.client import VnodeClient
@ -1147,24 +1147,13 @@ class CoreNetworkBase(NodeBase):
return all_links return all_links
def linkconfig( def linkconfig(
self, self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
netif: CoreInterface,
bw: float = None,
delay: float = None,
loss: float = None,
duplicate: float = None,
jitter: float = None,
netif2: float = None,
) -> None: ) -> None:
""" """
Configure link parameters by applying tc queuing disciplines on the interface. Configure link parameters by applying tc queuing disciplines on the interface.
:param netif: interface one :param netif: interface one
:param bw: bandwidth to set to :param options: options for configuring link
:param delay: packet delay to set to
:param loss: packet loss to set to
:param duplicate: duplicate percentage to set to
:param jitter: jitter to set to
:param netif2: interface two :param netif2: interface two
:return: nothing :return: nothing
""" """

View file

@ -12,6 +12,7 @@ import netaddr
from core import utils from core import utils
from core.constants import EBTABLES_BIN, TC_BIN from core.constants import EBTABLES_BIN, TC_BIN
from core.emulator.data import LinkData, NodeData from core.emulator.data import LinkData, NodeData
from core.emulator.emudata import LinkOptions
from core.emulator.enumerations import ( from core.emulator.enumerations import (
LinkTypes, LinkTypes,
MessageFlags, MessageFlags,
@ -441,24 +442,13 @@ class CoreNetwork(CoreNetworkBase):
ebq.ebchange(self) ebq.ebchange(self)
def linkconfig( def linkconfig(
self, self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
netif: CoreInterface,
bw: float = None,
delay: float = None,
loss: float = None,
duplicate: float = None,
jitter: float = None,
netif2: float = None,
) -> None: ) -> None:
""" """
Configure link parameters by applying tc queuing disciplines on the interface. Configure link parameters by applying tc queuing disciplines on the interface.
:param netif: interface one :param netif: interface one
:param bw: bandwidth to set to :param options: options for configuring link
:param delay: packet delay to set to
:param loss: packet loss to set to
:param duplicate: duplicate percentage to set to
:param jitter: jitter to set to
:param netif2: interface two :param netif2: interface two
:return: nothing :return: nothing
""" """
@ -466,6 +456,7 @@ class CoreNetwork(CoreNetworkBase):
tc = f"{TC_BIN} qdisc replace dev {devname}" tc = f"{TC_BIN} qdisc replace dev {devname}"
parent = "root" parent = "root"
changed = False changed = False
bw = options.bandwidth
if netif.setparam("bw", bw): if netif.setparam("bw", bw):
# from tc-tbf(8): minimum value for burst is rate / kernel_hz # from tc-tbf(8): minimum value for burst is rate / kernel_hz
burst = max(2 * netif.mtu, int(bw / 1000)) burst = max(2 * netif.mtu, int(bw / 1000))
@ -489,13 +480,17 @@ class CoreNetwork(CoreNetworkBase):
if netif.getparam("has_tbf"): if netif.getparam("has_tbf"):
parent = "parent 1:1" parent = "parent 1:1"
netem = "netem" netem = "netem"
delay = options.delay
changed = max(changed, netif.setparam("delay", delay)) changed = max(changed, netif.setparam("delay", delay))
loss = options.per
if loss is not None: if loss is not None:
loss = float(loss) loss = float(loss)
changed = max(changed, netif.setparam("loss", loss)) changed = max(changed, netif.setparam("loss", loss))
duplicate = options.dup
if duplicate is not None: if duplicate is not None:
duplicate = int(duplicate) duplicate = int(duplicate)
changed = max(changed, netif.setparam("duplicate", duplicate)) changed = max(changed, netif.setparam("duplicate", duplicate))
jitter = options.jitter
changed = max(changed, netif.setparam("jitter", jitter)) changed = max(changed, netif.setparam("jitter", jitter))
if not changed: if not changed:
return return

View file

@ -10,7 +10,7 @@ from typing import IO, TYPE_CHECKING, List, Optional, Tuple
from core import utils from core import utils
from core.constants import MOUNT_BIN, UMOUNT_BIN from core.constants import MOUNT_BIN, UMOUNT_BIN
from core.emulator.distributed import DistributedServer from core.emulator.distributed import DistributedServer
from core.emulator.emudata import InterfaceData from core.emulator.emudata import InterfaceData, LinkOptions
from core.emulator.enumerations import NodeTypes, TransportType from core.emulator.enumerations import NodeTypes, TransportType
from core.errors import CoreCommandError, CoreError from core.errors import CoreCommandError, CoreError
from core.nodes.base import CoreNetworkBase, CoreNodeBase from core.nodes.base import CoreNetworkBase, CoreNodeBase
@ -144,21 +144,14 @@ class PhysicalNode(CoreNodeBase):
self.net_client.device_up(netif.localname) self.net_client.device_up(netif.localname)
def linkconfig( def linkconfig(
self, self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None
netif: CoreInterface,
bw: float = None,
delay: float = None,
loss: float = None,
duplicate: float = None,
jitter: float = None,
netif2: CoreInterface = None,
) -> None: ) -> None:
""" """
Apply tc queing disciplines using linkconfig. Apply tc queing disciplines using linkconfig.
""" """
linux_bridge = CoreNetwork(session=self.session, start=False) linux_bridge = CoreNetwork(session=self.session, start=False)
linux_bridge.up = True linux_bridge.up = True
linux_bridge.linkconfig(netif, bw, delay, loss, duplicate, jitter, netif2) linux_bridge.linkconfig(netif, options, netif2)
del linux_bridge del linux_bridge
def newifindex(self) -> int: def newifindex(self) -> int: