diff --git a/README b/README deleted file mode 100644 index c3004eb0..00000000 --- a/README +++ /dev/null @@ -1,61 +0,0 @@ - -CORE: Common Open Research Emulator -Copyright (c)2005-2013 the Boeing Company. -See the LICENSE file included in this distribution. - -== ABOUT ======================================================================= -CORE is a tool for emulating networks using a GUI or Python scripts. The CORE -project site (1) is a good source of introductory information, with a manual, -screenshots, and demos about this software. Also a supplemental -Google Code page (2) hosts a wiki, blog, bug tracker, and quickstart guide. - - 1. http://www.nrl.navy.mil/itd/ncs/products/core - 2. http://code.google.com/p/coreemu/ - - -== BUILDING CORE =============================================================== - -To build this software you should use: - - ./bootstrap.sh - ./configure - make - sudo make install - -Here is what is installed with 'make install': - - /usr/local/bin/core-gui - /usr/local/sbin/core-daemon - /usr/local/sbin/[vcmd, vnoded, coresendmsg, core-cleanup.sh] - /usr/local/lib/core/* - /usr/local/share/core/* - /usr/local/lib/python2.6/dist-packages/core/* - /usr/local/lib/python2.6/dist-packages/[netns,vcmd].so - /etc/core/* - /etc/init.d/core - -See the manual for the software required for building CORE. - - -== RUNNING CORE ================================================================ - -First start the CORE services: - - sudo /etc/init.d/core-daemon start - -This automatically runs the core-daemon program. -Assuming the GUI is in your PATH, run the CORE GUI by typing the following: - - core-gui - -This launches the CORE GUI. You do not need to run the GUI as root. - -== SUPPORT ===================================================================== - -If you have questions, comments, or trouble, please use the CORE mailing lists: -- core-users for general comments and questions - http://pf.itd.nrl.navy.mil/mailman/listinfo/core-users -- core-dev for bugs, compile errors, and other development issues - http://pf.itd.nrl.navy.mil/mailman/listinfo/core-dev - - diff --git a/README.rst b/README.rst new file mode 100644 index 00000000..5fb323ac --- /dev/null +++ b/README.rst @@ -0,0 +1,87 @@ +==== +CORE +==== + +CORE: Common Open Research Emulator + +Copyright (c)2005-2013 the Boeing Company. + +See the LICENSE file included in this distribution. + +About +===== + +CORE is a tool for emulating networks using a GUI or Python scripts. The CORE +project site (1) is a good source of introductory information, with a manual, +screenshots, and demos about this software. The GitHub project (2) hosts the +source repos, wiki, and bug tracker. There is a deprecated +Google Code page (3) with the old wiki, blog, bug tracker, and quickstart guide. + +1. http://www.nrl.navy.mil/itd/ncs/products/core + +2. https://github.com/coreemu/core + +3. http://code.google.com/p/coreemu/ + +4. `Official Documentation`_ + +.. _Official Documentation: https://downloads.pf.itd.nrl.navy.mil/docs/core/core-html/index.html + + +Building CORE +============= + +To build this software you should use: + + ./bootstrap.sh + ./configure + make + sudo make install + +Note: You may need to pass the proxy settings to sudo make install: + sudo make install HTTP_PROXY= + +Here is what is installed with 'make install': + + /usr/local/bin/core-gui + /usr/local/sbin/core-daemon + /usr/local/sbin/[vcmd, vnoded, coresendmsg, core-cleanup.sh] + /usr/local/lib/core/* + /usr/local/share/core/* + /usr/local/lib/python2.6/dist-packages/core/* + /usr/local/lib/python2.6/dist-packages/[netns,vcmd].so + /etc/core/* + /etc/init.d/core + +See the manual for the software required for building CORE. + + +Running CORE +============ + +First start the CORE services: + + sudo /etc/init.d/core-daemon start + +This automatically runs the core-daemon program. +Assuming the GUI is in your PATH, run the CORE GUI by typing the following: + + core-gui + +This launches the CORE GUI. You do not need to run the GUI as root. + + +Support +======= + +If you have questions, comments, or trouble, please use the CORE mailing lists: + +- `core-users`_ for general comments and questions + +- `core-dev`_ for bugs, compile errors, and other development issues + + +.. _core-users: https://pf.itd.nrl.navy.mil/mailman/listinfo/core-users +.. _core-dev: https://pf.itd.nrl.navy.mil/mailman/listinfo/core-dev + + diff --git a/daemon/core/__init__.py b/daemon/core/__init__.py index 4a58c227..50d263c3 100644 --- a/daemon/core/__init__.py +++ b/daemon/core/__init__.py @@ -13,7 +13,5 @@ Pieces can be imported individually, for example from core.netns import vnode """ -__all__ = [] - # Automatically import all add-ons listed in addons.__all__ from addons import * diff --git a/daemon/core/emane/emanemanager.py b/daemon/core/emane/emanemanager.py index 6717bc4f..aa0dfe76 100644 --- a/daemon/core/emane/emanemanager.py +++ b/daemon/core/emane/emanemanager.py @@ -246,7 +246,9 @@ class EmaneManager(ConfigurableManager): # Adamson change: first check for iface config keyed by "node:ifc.name" # (so that nodes w/ multiple interfaces of same conftype can have # different configs for each separate interface) - key = 1000 * ifc.node.objid + ifc.netindex + key = 1000*ifc.node.objid + if ifc.netindex is not None: + key += ifc.netindex values = self.getconfig(key, conftype, None)[1] if not values: values = self.getconfig(ifc.node.objid, conftype, None)[1] diff --git a/daemon/core/netns/vnet.py b/daemon/core/netns/vnet.py index 5c1a0517..c1a17a19 100644 --- a/daemon/core/netns/vnet.py +++ b/daemon/core/netns/vnet.py @@ -301,12 +301,6 @@ class LxBrNet(PyCoreNet): snoop = "/sys/devices/virtual/net/%s/bridge/multicast_snooping" % self.brname if os.path.exists(snoop): open(snoop, "w").write('0') - - # turn on LLDP forwarding (disabled by default in linux) - lldpfile = "/sys/class/net/%s/bridge/group_fwd_mask" % self.brname - if os.path.exists(lldpfile): - open(lldpfile, "w").write('0x4000') - except subprocess.CalledProcessError: logger.exception("Error setting bridge parameters") diff --git a/daemon/core/netns/vnode.py b/daemon/core/netns/vnode.py index 334fe78b..2c2ccbb6 100644 --- a/daemon/core/netns/vnode.py +++ b/daemon/core/netns/vnode.py @@ -389,8 +389,12 @@ class SimpleLxcNode(PyCoreNode): :return: nothing """ if self.up: - self.cmd([constants.IP_BIN, "addr", "add", str(addr), - "dev", self.ifname(ifindex)]) + if ":" in str(addr): # check if addr is ipv6 + self.cmd([constants.IP_BIN, "addr", "add", str(addr), + "dev", self.ifname(ifindex)]) + else: + self.cmd([constants.IP_BIN, "addr", "add", str(addr), "broadcast", "+", + "dev", self.ifname(ifindex)]) self._netif[ifindex].addaddr(addr) def deladdr(self, ifindex, addr): diff --git a/daemon/core/service.py b/daemon/core/service.py index 5772b4cc..92b735fe 100644 --- a/daemon/core/service.py +++ b/daemon/core/service.py @@ -106,6 +106,10 @@ class CoreServices(ConfigurableManager): from core.services import startup self.is_startup_service = startup.Startup.is_startup_service + @classmethod + def add_service_path(cls, path): + cls.service_path.add(path) + def importcustom(self, path): """ Import services from a myservices directory. @@ -975,7 +979,7 @@ class CoreService(object): :return: nothing """ if key not in self.keys: - raise ValueError + raise ValueError('key `%s` not in `%s`' % (key, self.keys)) # this handles data conversion to int, string, and tuples if value: if key == "startidx": diff --git a/daemon/core/services/__init__.py b/daemon/core/services/__init__.py index db00a1d7..ddd5485d 100644 --- a/daemon/core/services/__init__.py +++ b/daemon/core/services/__init__.py @@ -4,4 +4,17 @@ Services Services available to nodes can be put in this directory. Everything listed in __all__ is automatically loaded by the main core module. """ -__all__ = ["quagga", "nrl", "xorp", "bird", "utility", "security", "ucarp", "dockersvc", "OvsService" , "ryuService" , 'startup' ] + +__all__ = [ + "quagga", + "nrl", + "xorp", + "bird", + "utility", + "security", + "ucarp", + "dockersvc", + "OvsService", + "RyuService", + "startup" +] diff --git a/daemon/core/services/nrl.py b/daemon/core/services/nrl.py index 2e9be941..5187d788 100644 --- a/daemon/core/services/nrl.py +++ b/daemon/core/services/nrl.py @@ -603,7 +603,7 @@ class MgenActor(NrlService): cfg = "#!/bin/sh\n" cfg += "# auto-generated by nrl.py:MgenActor.generateconfig()\n" comments = "" - cmd = "python /usr/local/bin/mgenBasicActor.py -n %s -a 0.0.0.0 -p 5555" % (node.name) + cmd = "mgenBasicActor.py -n %s -a 0.0.0.0" % node.name servicenames = map(lambda x: x._name, services) netifs = filter(lambda x: not getattr(x, 'control', False), node.netifs()) diff --git a/daemon/core/services/quagga.py b/daemon/core/services/quagga.py index d1786f21..251cef61 100644 --- a/daemon/core/services/quagga.py +++ b/daemon/core/services/quagga.py @@ -12,16 +12,11 @@ from core.misc import nodeutils from core.service import CoreService from core.service import ServiceManager -QUAGGA_USER = "root" -QUAGGA_GROUP = "root" -if os.uname()[0] == "FreeBSD": - QUAGGA_GROUP = "wheel" class Zebra(CoreService): _name = "zebra" _group = "Quagga" - _depends = ("vtysh",) _dirs = ("/usr/local/etc/quagga", "/var/run/quagga") _configs = ("/usr/local/etc/quagga/Quagga.conf", "quaggaboot.sh", "/usr/local/etc/quagga/vtysh.conf") @@ -53,16 +48,11 @@ class Zebra(CoreService): @classmethod def generateQuaggaConf(cls, node, services): - """ Returns configuration file text. Other services that depend on zebra - will have generatequaggaifcconfig() and generatequaggaconfig() - hooks that are invoked here. """ - # Check whether the node is running OVS - has_ovs = 0 - for s in services: - if s._name == "OvsService": - has_ovs =1 - + Returns configuration file text. Other services that depend on zebra + will have generatequaggaifcconfig() and generatequaggaconfig() + hooks that are invoked here. + """ # we could verify here that filename == Quagga.conf cfg = "" for ifc in node.netifs(): @@ -72,7 +62,7 @@ class Zebra(CoreService): ifnumstr = re.findall(r"\d+", ifc.name) ifnum = ifnumstr[0] ifname = "rtr%s" % ifnum - + cfg += "interface %s\n" % ifname #cfg += "interface %s\n" % ifc.name # include control interfaces in addressing but not routing daemons @@ -147,8 +137,6 @@ QUAGGA_CONF=%s QUAGGA_SBIN_SEARCH=%s QUAGGA_BIN_SEARCH=%s QUAGGA_STATE_DIR=%s -QUAGGA_USER=%s -QUAGGA_GROUP=%s searchforprog() { @@ -177,21 +165,6 @@ confcheck() fi } -waitforvtyfiles() -{ - for f in "$@"; do - count=1 - until [ -e $QUAGGA_STATE_DIR/$f ]; do - if [ $count -eq 10 ]; then - echo "ERROR: vty file not found: $QUAGGA_STATE_DIR/$f" >&2 - return 1 - fi - sleep 0.1 - count=$(($count + 1)) - done - done -} - bootdaemon() { QUAGGA_SBIN_DIR=$(searchforprog $1 $QUAGGA_SBIN_SEARCH) @@ -203,54 +176,54 @@ bootdaemon() flags="" - if [ "$1" != "zebra" ]; then - waitforvtyfiles zebra.vty - fi - if [ "$1" = "xpimd" ] && \\ grep -E -q '^[[:space:]]*router[[:space:]]+pim6[[:space:]]*$' $QUAGGA_CONF; then flags="$flags -6" fi - $QUAGGA_SBIN_DIR/$1 $flags -u $QUAGGA_USER -g $QUAGGA_GROUP -d + $QUAGGA_SBIN_DIR/$1 $flags -d + if [ "$?" != "0" ]; then + echo "ERROR: Quagga's '$1' daemon failed to start!:" + return 1 + fi } -bootvtysh() +bootquagga() { - QUAGGA_BIN_DIR=$(searchforprog $1 $QUAGGA_BIN_SEARCH) + QUAGGA_BIN_DIR=$(searchforprog 'vtysh' $QUAGGA_BIN_SEARCH) if [ "z$QUAGGA_BIN_DIR" = "z" ]; then - echo "ERROR: Quagga's '$1' daemon not found in search path:" - echo " $QUAGGA_SBIN_SEARCH" + echo "ERROR: Quagga's 'vtysh' program not found in search path:" + echo " $QUAGGA_BIN_SEARCH" return 1 fi - vtyfiles="zebra.vty" + # fix /var/run/quagga permissions + id -u quagga 2>/dev/null >/dev/null + if [ "$?" = "0" ]; then + chown quagga $QUAGGA_STATE_DIR + fi + + bootdaemon "zebra" for r in rip ripng ospf6 ospf bgp babel; do if grep -q "^router \<${r}\>" $QUAGGA_CONF; then - vtyfiles="$vtyfiles ${r}d.vty" + bootdaemon "${r}d" fi done if grep -E -q '^[[:space:]]*router[[:space:]]+pim6?[[:space:]]*$' $QUAGGA_CONF; then - vtyfiles="$vtyfiles xpimd.vty" + bootdaemon "xpimd" fi - # wait for Quagga daemon vty files to appear before invoking vtysh - waitforvtyfiles $vtyfiles - $QUAGGA_BIN_DIR/vtysh -b } -confcheck -if [ "x$1" = "x" ]; then - echo "ERROR: missing the name of the Quagga daemon to boot" +if [ "$1" != "zebra" ]; then + echo "WARNING: '$1': all Quagga daemons are launched by the 'zebra' service!" exit 1 -elif [ "$1" = "vtysh" ]; then - bootvtysh $1 -else - bootdaemon $1 fi -""" % (cls._configs[0], quagga_sbin_search, quagga_bin_search, constants.QUAGGA_STATE_DIR, QUAGGA_USER, QUAGGA_GROUP) +confcheck +bootquagga +""" % (cls._configs[0], quagga_sbin_search, quagga_bin_search, constants.QUAGGA_STATE_DIR) class QuaggaService(CoreService): @@ -308,7 +281,7 @@ class QuaggaService(CoreService): return "" @classmethod - def generatequaggaconfig(cls, node, services): + def generatequaggaconfig(cls, node): return "" @@ -319,9 +292,9 @@ class Ospfv2(QuaggaService): unified Quagga.conf file. """ _name = "OSPFv2" - _startup = ("sh quaggaboot.sh ospfd",) - _shutdown = ("killall ospfd",) - _validate = ("pidof ospfd",) + _startup = () + _shutdown = ("killall ospfd", ) + _validate = ("pidof ospfd", ) _ipv4_routing = True @staticmethod @@ -353,7 +326,7 @@ class Ospfv2(QuaggaService): return "" @classmethod - def generatequaggaconfig(cls, node, services): + def generatequaggaconfig(cls, node): cfg = "router ospf\n" rtrid = cls.routerid(node) cfg += " router-id %s\n" % rtrid @@ -394,9 +367,9 @@ class Ospfv3(QuaggaService): unified Quagga.conf file. """ _name = "OSPFv3" - _startup = ("sh quaggaboot.sh ospf6d",) - _shutdown = ("killall ospf6d",) - _validate = ("pidof ospf6d",) + _startup = () + _shutdown = ("killall ospf6d", ) + _validate = ("pidof ospf6d", ) _ipv4_routing = True _ipv6_routing = True @@ -438,13 +411,7 @@ class Ospfv3(QuaggaService): return "" @classmethod - def generatequaggaconfig(cls, node, services): - # Check whether the node is running OVS - has_ovs = 0 - for s in services: - if s._name == "OvsService": - has_ovs =1 - + def generatequaggaconfig(cls, node): cfg = "router ospf6\n" rtrid = cls.routerid(node) cfg += " router-id %s\n" % rtrid @@ -457,7 +424,7 @@ class Ospfv3(QuaggaService): ifnumstr = re.findall(r"\d+", ifc.name) ifnum = ifnumstr[0] ifname = "rtr%s" % ifnum - + cfg += " interface %s area 0.0.0.0\n" % ifc.name cfg += "!\n" return cfg @@ -508,6 +475,7 @@ class Ospfv3mdr(Ospfv3): else: return cfg + class Bgp(QuaggaService): """ The BGP service provides interdomain routing. @@ -515,15 +483,15 @@ class Bgp(QuaggaService): having the same AS number. """ _name = "BGP" - _startup = ("sh quaggaboot.sh bgpd",) - _shutdown = ("killall bgpd",) - _validate = ("pidof bgpd",) + _startup = () + _shutdown = ("killall bgpd", ) + _validate = ("pidof bgpd", ) _custom_needed = True _ipv4_routing = True _ipv6_routing = True @classmethod - def generatequaggaconfig(cls, node, services): + def generatequaggaconfig(cls, node): cfg = "!\n! BGP configuration\n!\n" cfg += "! You should configure the AS number below,\n" cfg += "! along with this router's peers.\n!\n" @@ -534,18 +502,19 @@ class Bgp(QuaggaService): cfg += "! neighbor 1.2.3.4 remote-as 555\n!\n" return cfg + class Rip(QuaggaService): """ The RIP service provides IPv4 routing for wired networks. """ _name = "RIP" - _startup = ("sh quaggaboot.sh ripd",) - _shutdown = ("killall ripd",) - _validate = ("pidof ripd",) + _startup = () + _shutdown = ("killall ripd", ) + _validate = ("pidof ripd", ) _ipv4_routing = True @classmethod - def generatequaggaconfig(cls, node, services): + def generatequaggaconfig(cls, node): cfg = """\ router rip redistribute static @@ -556,18 +525,19 @@ router rip """ return cfg + class Ripng(QuaggaService): """ The RIP NG service provides IPv6 routing for wired networks. """ _name = "RIPNG" - _startup = ("sh quaggaboot.sh ripngd",) - _shutdown = ("killall ripngd",) - _validate = ("pidof ripngd",) + _startup = () + _shutdown = ("killall ripngd", ) + _validate = ("pidof ripngd", ) _ipv6_routing = True @classmethod - def generatequaggaconfig(cls, node, services): + def generatequaggaconfig(cls, node): cfg = """\ router ripng redistribute static @@ -578,36 +548,24 @@ router ripng """ return cfg + class Babel(QuaggaService): """ The Babel service provides a loop-avoiding distance-vector routing protocol for IPv6 and IPv4 with fast convergence properties. """ _name = "Babel" - _startup = ("sh quaggaboot.sh babeld",) - _shutdown = ("killall babeld",) - _validate = ("pidof babeld",) + _startup = () + _shutdown = ("killall babeld", ) + _validate = ("pidof babeld", ) _ipv6_routing = True @classmethod - def generatequaggaconfig(cls, node, services): - # Check whether the node is running OVS - has_ovs = 0 - for s in services: - if s._name == "OvsService": - has_ovs =1 - + def generatequaggaconfig(cls, node): cfg = "router babel\n" for ifc in node.netifs(): - if hasattr(ifc, 'control') and ifc.control is True: + if hasattr(ifc, "control") and ifc.control is True: continue - if has_ovs == 0: - ifname = ifc.name - else: - ifnumstr = re.findall(r"\d+", ifc.name) - ifnum = ifnumstr[0] - ifname = "rtr%s" % ifnum - cfg += " network %s\n" % ifc.name cfg += " redistribute static\n redistribute connected\n" return cfg @@ -620,37 +578,23 @@ class Babel(QuaggaService): else: return " babel wired\n babel split-horizon\n" + class Xpimd(QuaggaService): """ PIM multicast routing based on XORP. """ _name = 'Xpimd' - _startup = ('sh quaggaboot.sh xpimd',) - _shutdown = ('killall xpimd',) - _validate = ('pidof xpimd',) + _startup = () + _shutdown = ('killall xpimd', ) + _validate = ('pidof xpimd', ) _ipv4_routing = True @classmethod - def generatequaggaconfig(cls, node, services): - # Check whether the node is running OVS - has_ovs = 0 - for s in services: - if s._name == "OvsService": - has_ovs =1 - if has_ovs == 0: - ifname = 'eth0' - else: - ifname = 'rtr0' - + def generatequaggaconfig(cls, node): + ifname = 'eth0' for ifc in node.netifs(): if ifc.name != 'lo': - if has_ovs == 0: - ifname = ifc.name - else: - ifnumstr = re.findall(r"\d+", ifc.name) - ifnum = ifnumstr[0] - ifname = "rtr%s" % ifnum - + ifname = ifc.name break cfg = 'router mfea\n!\n' cfg += 'router igmp\n!\n' @@ -665,20 +609,6 @@ class Xpimd(QuaggaService): def generatequaggaifcconfig(cls, node, ifc): return ' ip mfea\n ip igmp\n ip pim\n' -class Vtysh(CoreService): - """ - Simple service to run vtysh -b (boot) after all Quagga daemons have - started. - """ - _name = "vtysh" - _group = "Quagga" - _startindex = 45 - _startup = ("sh quaggaboot.sh vtysh",) - _shutdown = () - - @classmethod - def generateconfig(cls, node, filename, services): - return "" def load_services(): ServiceManager.add(Zebra) @@ -690,4 +620,3 @@ def load_services(): ServiceManager.add(Ripng) ServiceManager.add(Babel) ServiceManager.add(Xpimd) - ServiceManager.add(Vtysh) diff --git a/daemon/core/xen/xen.py b/daemon/core/xen/xen.py index 578fab3a..8d7e4ac5 100644 --- a/daemon/core/xen/xen.py +++ b/daemon/core/xen/xen.py @@ -102,7 +102,6 @@ class XenNode(PyCoreNode): # 'sh quaggaboot.sh zebra', # 'sh quaggaboot.sh ospfd', # 'sh quaggaboot.sh ospf6d', - 'sh quaggaboot.sh vtysh', 'killall zebra', 'killall ospfd', 'killall ospf6d', diff --git a/daemon/core/xml/xmlparser1.py b/daemon/core/xml/xmlparser1.py index c37a3fda..c1861526 100644 --- a/daemon/core/xml/xmlparser1.py +++ b/daemon/core/xml/xmlparser1.py @@ -851,12 +851,10 @@ class CoreDocumentParser1(object): def parse_default_services(self): # defaults from the CORE GUI self.default_services = { - 'router': ['zebra', 'OSPFv2', 'OSPFv3', 'vtysh', 'IPForward'], + 'router': ['zebra', 'OSPFv2', 'OSPFv3', 'IPForward'], 'host': ['DefaultRoute', 'SSH'], 'PC': ['DefaultRoute', ], - 'mdr': ['zebra', 'OSPFv3MDR', 'vtysh', 'IPForward'], - # 'prouter': ['zebra', 'OSPFv2', 'OSPFv3', 'vtysh', 'IPForward'], - # 'xen': ['zebra', 'OSPFv2', 'OSPFv3', 'vtysh', 'IPForward'], + 'mdr': ['zebra', 'OSPFv3MDR', 'IPForward'], } default_services = xmlutils.get_first_child_by_tag_name(self.scenario, 'CORE:defaultservices') if not default_services: diff --git a/daemon/core/xml/xmlwriter1.py b/daemon/core/xml/xmlwriter1.py index 07c28ae9..5dc062f0 100644 --- a/daemon/core/xml/xmlwriter1.py +++ b/daemon/core/xml/xmlwriter1.py @@ -603,7 +603,7 @@ class DeviceElement(NamedXmlElement): device_type = DevType.HOST if device_type is None: - raise Exception + raise ValueError("unknown device type: %s" % core_device_type) NamedXmlElement.__init__(self, scen_plan, parent, device_type, device_object.name) diff --git a/daemon/data/core.conf b/daemon/data/core.conf index 9c4780e3..8ee2a532 100644 --- a/daemon/data/core.conf +++ b/daemon/data/core.conf @@ -29,12 +29,12 @@ quagga_sbin_search = "/usr/local/sbin /usr/sbin /usr/lib/quagga" # # # uncomment and edit to establish a distributed control backchannel -#controlnet = core1:172.16.1.0/24 core2:172.16.2.0/24 core3:172.16.3.0/24 core4 :172.16.4.0/24 core5:172.16.5.0/24 +#controlnet = core1:172.16.1.0/24 core:172.16.2.0/24 core3:172.16.3.0/24 core4 :172.16.4.0/24 core5:172.16.5.0/24 # uncomment and edit to establish distributed auxiliary control channels. -#controlnet1 = core1:172.17.1.0/24 core2:172.17.2.0/24 core3:172.17.3.0/24 core4 :172.17.4.0/24 core5:172.17.5.0/24 -#controlnet2 = core1:172.18.1.0/24 core2:172.18.2.0/24 core3:172.18.3.0/24 core4 :172.18.4.0/24 core5:172.18.5.0/24 -#controlnet3 = core1:172.19.1.0/24 core2:172.19.2.0/24 core3:172.19.3.0/24 core4 :172.19.4.0/24 core5:172.19.5.0/24 +#controlnet1 = core1:172.17.1.0/24 core:172.17.2.0/24 core3:172.17.3.0/24 core4 :172.17.4.0/24 core5:172.17.5.0/24 +#controlnet2 = core1:172.18.1.0/24 core:172.18.2.0/24 core3:172.18.3.0/24 core4 :172.18.4.0/24 core5:172.18.5.0/24 +#controlnet3 = core1:172.19.1.0/24 core:172.19.2.0/24 core3:172.19.3.0/24 core4 :172.19.4.0/24 core5:172.19.5.0/24 # uncomment and edit to assign host interfaces to auxilary control channels # for use in connecting with other servers in a distributed environments. @@ -57,7 +57,7 @@ emane_platform_port = 8101 emane_transform_port = 8201 emane_event_generate = True emane_event_monitor = False -emane_models = RfPipe, Ieee80211abg, CommEffect, Bypass +emane_models = RfPipe, Ieee80211abg, CommEffect, Bypass, Tdma # EMANE log level range [0,4] default: 2 #emane_log_level = 2 emane_realtime = True diff --git a/daemon/examples/netns/emane80211.py b/daemon/examples/netns/emane80211.py index eab1839d..857b577d 100755 --- a/daemon/examples/netns/emane80211.py +++ b/daemon/examples/netns/emane80211.py @@ -76,7 +76,7 @@ def main(): values[names.index('propagationmodel')] = '2ray' session.emane.setconfig(wlan.objid, EmaneIeee80211abgModel.name, values) - services_str = "zebra|OSPFv3MDR|vtysh|IPForward" + services_str = "zebra|OSPFv3MDR|IPForward" print "creating %d nodes with addresses from %s" % \ (options.numnodes, prefix) diff --git a/daemon/examples/netns/howmanynodes.py b/daemon/examples/netns/howmanynodes.py index 92d8ec3a..90f8b727 100755 --- a/daemon/examples/netns/howmanynodes.py +++ b/daemon/examples/netns/howmanynodes.py @@ -97,7 +97,7 @@ def main(): parser.add_option("-s", "--services", dest="services", type=str, help="pipe-delimited list of services added to each " "node (default = %s)\n(Example: zebra|OSPFv2|OSPFv3|" - "vtysh|IPForward)" % parser.defaults["services"]) + "IPForward)" % parser.defaults["services"]) def usage(msg=None, err=0): sys.stdout.write("\n") diff --git a/daemon/ns3/examples/ns3wifirandomwalk.py b/daemon/ns3/examples/ns3wifirandomwalk.py index a02eb69a..205b1157 100755 --- a/daemon/ns3/examples/ns3wifirandomwalk.py +++ b/daemon/ns3/examples/ns3wifirandomwalk.py @@ -66,7 +66,7 @@ def wifisession(opt): wifi.phy.Set("RxGain", ns.core.DoubleValue(18.0)) prefix = ipaddr.IPv4Prefix("10.0.0.0/16") - services_str = "zebra|OSPFv3MDR|vtysh|IPForward" + services_str = "zebra|OSPFv3MDR|IPForward" nodes = [] for i in xrange(1, opt.numnodes + 1): node = session.addnode(name = "n%d" % i) diff --git a/daemon/sbin/core-daemon b/daemon/sbin/core-daemon index d14496d3..2b54dfd0 100755 --- a/daemon/sbin/core-daemon +++ b/daemon/sbin/core-daemon @@ -163,7 +163,6 @@ def sighandler(signum, stackframe): signal.signal(signal.SIGHUP, sighandler) signal.signal(signal.SIGINT, sighandler) -signal.signal(signal.SIGPIPE, sighandler) signal.signal(signal.SIGTERM, sighandler) signal.signal(signal.SIGUSR1, sighandler) signal.signal(signal.SIGUSR2, sighandler) diff --git a/doc/emane.rst b/doc/emane.rst index 18cf2243..b4da0c69 100644 --- a/doc/emane.rst +++ b/doc/emane.rst @@ -111,7 +111,7 @@ Here are quick instructions for installing all EMANE packages: :: # install dependencies - sudo apt-get install libssl-dev libxml-lixbml-perl libxml-simple-perl + sudo apt-get install libssl-dev libxml-libxml-perl libxml-simple-perl # download and install EMANE 0.8.1 export URL=http://downloads.pf.itd.nrl.navy.mil/emane/0.8.1-r2 wget $URL/emane-0.8.1-release-2.ubuntu-12_04.amd64.tgz diff --git a/doc/usage.rst b/doc/usage.rst index d0dc35cd..ec6e6028 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -1448,13 +1448,13 @@ Here are the default node types and their services: .. index:: Xen .. index:: physical nodes -* *router* - zebra, OSFPv2, OSPFv3, vtysh, and IPForward services for IGP +* *router* - zebra, OSFPv2, OSPFv3, and IPForward services for IGP link-state routing. * *host* - DefaultRoute and SSH services, representing an SSH server having a default route when connected directly to a router. * *PC* - DefaultRoute service for having a default route when connected directly to a router. -* *mdr* - zebra, OSPFv3MDR, vtysh, and IPForward services for +* *mdr* - zebra, OSPFv3MDR, and IPForward services for wireless-optimized MANET Designated Router routing. * *prouter* - a physical router, having the same default services as the *router* node type; for incorporating Linux testbed machines into an diff --git a/gui/configs/sample1.imn b/gui/configs/sample1.imn index c394bbe6..912f1e71 100644 --- a/gui/configs/sample1.imn +++ b/gui/configs/sample1.imn @@ -105,7 +105,7 @@ node n5 { labelcoords {540.0 376.0} interface-peer {eth0 n10} interface-peer {eth1 n15} - services {zebra OSPFv2 OSPFv3MDR vtysh IPForward} + services {zebra OSPFv2 OSPFv3MDR IPForward} custom-config { custom-config-id service:zebra custom-command zebra diff --git a/gui/configs/sample10-kitchen-sink.imn b/gui/configs/sample10-kitchen-sink.imn index a9e21a4a..d5463952 100644 --- a/gui/configs/sample10-kitchen-sink.imn +++ b/gui/configs/sample10-kitchen-sink.imn @@ -283,7 +283,7 @@ node n11 { } } - services {zebra OSPFv2 OSPFv3MDR vtysh IPForward} + services {zebra OSPFv2 OSPFv3MDR IPForward} } node n12 { @@ -517,7 +517,7 @@ node n20 { } } - services {zebra OSPFv2 OSPFv3MDR vtysh IPForward} + services {zebra OSPFv2 OSPFv3MDR IPForward} } node n21 { diff --git a/gui/configs/sample3-bgp.imn b/gui/configs/sample3-bgp.imn index f782585e..d4a396ae 100644 --- a/gui/configs/sample3-bgp.imn +++ b/gui/configs/sample3-bgp.imn @@ -20,7 +20,7 @@ node n1 { interface-peer {eth1 n2} interface-peer {eth2 n3} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -82,7 +82,7 @@ node n2 { interface-peer {eth1 n16} interface-peer {eth2 n6} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -140,7 +140,7 @@ node n3 { interface-peer {eth0 n4} interface-peer {eth1 n1} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -197,7 +197,7 @@ node n4 { interface-peer {eth0 n3} interface-peer {eth1 n7} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -258,7 +258,7 @@ node n5 { interface-peer {eth0 n7} interface-peer {eth1 n6} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -323,7 +323,7 @@ node n6 { interface-peer {eth0 n5} interface-peer {eth1 n2} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -376,7 +376,7 @@ node n7 { interface-peer {eth0 n5} interface-peer {eth1 n4} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf @@ -555,7 +555,7 @@ node n16 { interface-peer {eth0 n1} interface-peer {eth1 n2} canvas c1 - services {zebra BGP vtysh IPForward} + services {zebra BGP IPForward} custom-config { custom-config-id service:zebra:/usr/local/etc/quagga/Quagga.conf custom-command /usr/local/etc/quagga/Quagga.conf diff --git a/gui/configs/sample4-nrlsmf.imn b/gui/configs/sample4-nrlsmf.imn index a1b08b53..165c424f 100644 --- a/gui/configs/sample4-nrlsmf.imn +++ b/gui/configs/sample4-nrlsmf.imn @@ -65,7 +65,7 @@ node n1 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_green.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -101,7 +101,7 @@ node n2 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_green.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -137,7 +137,7 @@ node n3 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_green.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -173,7 +173,7 @@ node n4 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_green.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -209,7 +209,7 @@ node n5 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_green.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -245,7 +245,7 @@ node n6 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -281,7 +281,7 @@ node n7 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -317,7 +317,7 @@ node n8 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -353,7 +353,7 @@ node n9 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh @@ -389,7 +389,7 @@ node n10 { canvas c1 interface-peer {eth0 n11} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif - services {zebra OSPFv3MDR vtysh SMF IPForward UserDefined} + services {zebra OSPFv3MDR SMF IPForward UserDefined} custom-config { custom-config-id service:UserDefined:custom-post-config-commands.sh custom-command custom-post-config-commands.sh diff --git a/gui/configs/sample5-mgen.imn b/gui/configs/sample5-mgen.imn index 925266c4..e27b55a7 100644 --- a/gui/configs/sample5-mgen.imn +++ b/gui/configs/sample5-mgen.imn @@ -51,7 +51,7 @@ node n1 { cmdup=('sh mgen.sh', ) } } - services {zebra OSPFv2 OSPFv3 vtysh IPForward UserDefined} + services {zebra OSPFv2 OSPFv3 IPForward UserDefined} } node n2 { @@ -101,7 +101,7 @@ node n2 { mgen input send_$HN.mgn output $LOGDIR/mgen_$HN.log > /dev/null 2> /dev/null < /dev/null & } } - services {zebra OSPFv2 OSPFv3 vtysh IPForward UserDefined} + services {zebra OSPFv2 OSPFv3 IPForward UserDefined} } link l1 { diff --git a/gui/configs/sample8-ipsec-service.imn b/gui/configs/sample8-ipsec-service.imn index d1274c6f..ba409185 100644 --- a/gui/configs/sample8-ipsec-service.imn +++ b/gui/configs/sample8-ipsec-service.imn @@ -354,7 +354,7 @@ node n1 { } } - services {zebra OSPFv2 OSPFv3 vtysh IPForward IPsec} + services {zebra OSPFv2 OSPFv3 IPForward IPsec} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif } @@ -528,7 +528,7 @@ node n2 { } } - services {zebra OSPFv2 OSPFv3 vtysh IPForward IPsec} + services {zebra OSPFv2 OSPFv3 IPForward IPsec} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif } @@ -697,7 +697,7 @@ node n3 { } } - services {zebra OSPFv2 OSPFv3 vtysh IPForward IPsec} + services {zebra OSPFv2 OSPFv3 IPForward IPsec} custom-image $CORE_DATA_DIR/icons/normal/router_red.gif } diff --git a/gui/editor.tcl b/gui/editor.tcl index efc1aee2..e558cda5 100644 --- a/gui/editor.tcl +++ b/gui/editor.tcl @@ -1484,7 +1484,7 @@ proc addInterfaceCommand { node parentmenu txt cmd state isnodecmd } { $parentmenu add cascade -label $txt -menu $childmenu -state $state if { ! $isnodecmd } { if { $g_current_session == 0 } { set state disabled } - set ssid [shortSessionID $g_current_session] + set ssid [shortSessionID $g_current_session] } foreach ifc [ifcList $node] { set addr [lindex [getIfcIPv4addr $node $ifc] 0] @@ -1492,10 +1492,11 @@ proc addInterfaceCommand { node parentmenu txt cmd state isnodecmd } { if { $isnodecmd } { ;# run command in a node set icmd "spawnShell $node \"$cmd $ifc\"" } else { ;# exec a command directly - set nodenum [string range $node 1 end] + set node_num [string range $node 1 end] + set hex [format "%x" $node_num] set ifnum [string range $ifc 3 end] - set localifc veth$nodenum.$ifnum.$ssid - set icmd "exec $cmd $localifc &" + set ifname "veth$hex\\.$ifnum\\.$ssid" + set icmd "exec $cmd $ifname &" } $childmenu add command -label "$ifc$addr" -state $state -command $icmd } diff --git a/gui/nodes.tcl b/gui/nodes.tcl index dfb1c7dc..20d8853d 100644 --- a/gui/nodes.tcl +++ b/gui/nodes.tcl @@ -15,18 +15,18 @@ if { $execMode == "interactive" } { # these are the default node types when nodes.conf does not exist # index {name normal-icon tiny-icon services type metadata} array set g_node_types_default { - 1 {router router.gif router.gif {zebra OSPFv2 OSPFv3 vtysh IPForward} \ + 1 {router router.gif router.gif {zebra OSPFv2 OSPFv3 IPForward} \ netns {built-in type for routing}} 2 {host host.gif host.gif {DefaultRoute SSH} \ netns {built-in type for servers}} 3 {PC pc.gif pc.gif {DefaultRoute} \ netns {built-in type for end hosts}} - 4 {mdr mdr.gif mdr.gif {zebra OSPFv3MDR vtysh IPForward} \ + 4 {mdr mdr.gif mdr.gif {zebra OSPFv3MDR IPForward} \ netns {built-in type for wireless routers}} 5 {prouter router_green.gif router_green.gif \ - {zebra OSPFv2 OSPFv3 vtysh IPForward} \ + {zebra OSPFv2 OSPFv3 IPForward} \ physical {built-in type for physical nodes}} - 6 {xen xen.gif xen.gif {zebra OSPFv2 OSPFv3 vtysh IPForward} \ + 6 {xen xen.gif xen.gif {zebra OSPFv2 OSPFv3 IPForward} \ xen {built-in type for Xen PVM domU router}} 7 {OVS lanswitch.gif lanswitch.gif {DefaultRoute SSH OvsService} OVS {} } diff --git a/gui/util.tcl b/gui/util.tcl index 88c7cb3b..204694b0 100644 --- a/gui/util.tcl +++ b/gui/util.tcl @@ -160,7 +160,7 @@ proc upgradeNetworkConfigToServices { } { set bgp [netconfFetchSection $node "router bgp"] if { $ospfv2 != "" || $ospfv3 != "" || $rip != "" || $ripng != "" } { set cfg "" - set services "zebra vtysh IPForward" + set services "zebra IPForward" foreach ifc [ifcList $node] { lappend cfg "interface $ifc" set ifccfg [netconfFetchSection $node "interface $ifc"] @@ -1113,7 +1113,7 @@ proc get_text_editor { want_default } { # variable, then find the first in the list of terminals that exists on the # system set TERMS "{gnome-terminal -x} {lxterminal -e} {konsole -e} {xterm -e}" -set TERMS "$TERMS {aterm -e} {eterm -e} {rxvt -e} {xfce4-terminal -e}" +set TERMS "$TERMS {aterm -e} {eterm -e} {rxvt -e} {xfce4-terminal -x}" proc get_term_prog { want_default } { global g_prefs env TERMS @@ -1130,8 +1130,13 @@ proc get_term_prog { want_default } { } if { $term != "" } { set arg "-e" - # gnome-terminal has problem w/subsequent arguments after -e, needs -x - if { [file tail $term] == "gnome-terminal" } { set arg "-x" } + # gnome-terminal and xfce4-terminal have problems w/subsequent + # arguments after -e, needs -x + set basename [file tail $term] + if {[lsearch -exact \ + {"gnome-terminal" "xfce4-terminal"} $basename] >= 0} { + set arg "-x" + } set term "$term $arg" } diff --git a/gui/widget.tcl b/gui/widget.tcl index ed84ccf9..12c40499 100644 --- a/gui/widget.tcl +++ b/gui/widget.tcl @@ -572,7 +572,7 @@ proc exec_observer_callback { node execnum cmd result status } { ##### ##### ################################################################################ -array set thruConfig { show 1 avg 1 thresh 250.0 width 10 color #FF0000 } +array set thruConfig { show 1 up 1 down 1 avg 1 thresh 250.0 width 10 color #FF0000 } # netgraph names of pipe nodes array set throughput_cache { } @@ -597,7 +597,12 @@ proc widget_thru_config {} { checkbutton $wi.tlab.avg \ -text "Use exponentially weighted moving average" \ -variable thruConfig(avg) - pack $wi.tlab.show_thru $wi.tlab.avg -side top -anchor w -padx 4 + checkbutton $wi.tlab.down \ + -text "Include transmissions" -variable thruConfig(down) + checkbutton $wi.tlab.up \ + -text "Include receptions" -variable thruConfig(up) + pack $wi.tlab.show_thru $wi.tlab.avg $wi.tlab.down \ + $wi.tlab.up -side top -anchor w -padx 4 pack $wi.tlab -side top frame $wi.msg -borderwidth 4 @@ -807,7 +812,14 @@ proc widget_thru_periodic { now } { set div [expr { (1000.0 / 8.0) * $dt }] set kbps_down [expr { ([lindex $bytes 0]-[lindex $bytes2 0]) / $div }] set kbps_up [expr { ([lindex $bytes 1]-[lindex $bytes2 1]) / $div }] - set kbps [expr {$kbps_down + $kbps_up}] + set kbps 0.0 + if { $thruConfig(up) } { + set kbps [expr {$kbps + $kbps_up}] + } + if { $thruConfig(down) } { + set kbps [expr {$kbps + $kbps_down}] + } + #set kbps [expr {$kbps_down + $kbps_up}] if { $thruConfig(avg) } { if { ![info exists link_thru_avg_stats($key)] } { @@ -907,6 +919,7 @@ proc getstats_bytes_netgraph { raw_input } { } proc getstats_link_ifname { link } { + global g_current_session set lnode1 [lindex [linkPeers $link] 0] set lnode2 [lindex [linkPeers $link] 1] @@ -920,11 +933,10 @@ proc getstats_link_ifname { link } { set ifname [ifcByPeer $lnode2 $lnode1] } if { $node_num < 0 } { return "" } - - # TODO: need to determine session number used by daemon - # instead this uses a '*' character for a regexp match against - # the interfaces in /proc/net/dev - set ifname "veth$node_num\\.[string range $ifname 3 end]\\.*" + set ssid [shortSessionID $g_current_session] + set hex [format "%x" $node_num] + set ifnum [string range $ifname 3 end] + set ifname "veth$hex.$ifnum.$ssid" return $ifname } diff --git a/packaging/rpm/core.spec.in b/packaging/rpm/core.spec.in index 1a2cc9e3..7cf28a7b 100644 --- a/packaging/rpm/core.spec.in +++ b/packaging/rpm/core.spec.in @@ -32,12 +32,18 @@ Requires: procps-ng %if %{with_kernel_modules_extra} Requires: kernel-modules-extra %endif +%if 0%{?fedora} >= 25 +Requires: iproute-tc +%endif BuildRequires: make automake autoconf libev-devel python-devel bridge-utils ebtables iproute net-tools ImageMagick help2man %if 0%{?el6} BuildRequires: procps %else BuildRequires: procps-ng %endif +%if 0%{?fedora} >= 25 +BuildRequires: iproute-tc +%endif Provides: core-daemon # python-sphinx %description daemon diff --git a/scripts/core-daemon.service.in b/scripts/core-daemon.service.in index 657c160f..b0c4a7f2 100644 --- a/scripts/core-daemon.service.in +++ b/scripts/core-daemon.service.in @@ -6,6 +6,7 @@ After=network.target Type=forking PIDFile=/var/run/core-daemon.pid ExecStart=@PYTHON@ @SBINDIR@/core-daemon -d +TasksMax=infinity [Install] WantedBy=multi-user.target