initial commit after bringing over cleaned up code and testing some examples
This commit is contained in:
parent
c4858e6e0d
commit
00f4ebf5a9
93 changed files with 15189 additions and 13083 deletions
|
@ -1,24 +1,19 @@
|
|||
#
|
||||
# CORE
|
||||
# Copyright (c)2011-2012 the Boeing Company.
|
||||
# See the LICENSE file included in this distribution.
|
||||
#
|
||||
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
|
||||
#
|
||||
'''
|
||||
"""
|
||||
xorp.py: defines routing services provided by the XORP routing suite.
|
||||
'''
|
||||
"""
|
||||
|
||||
import os
|
||||
from core.misc import log
|
||||
from core.service import CoreService
|
||||
from core.service import ServiceManager
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
from core.service import CoreService, addservice
|
||||
from core.misc.ipaddr import IPv4Prefix
|
||||
from core.constants import *
|
||||
|
||||
class XorpRtrmgr(CoreService):
|
||||
''' XORP router manager service builds a config.boot file based on other
|
||||
"""
|
||||
XORP router manager service builds a config.boot file based on other
|
||||
enabled XORP services, and launches necessary daemons upon startup.
|
||||
'''
|
||||
"""
|
||||
_name = "xorp_rtrmgr"
|
||||
_group = "XORP"
|
||||
_depends = ()
|
||||
|
@ -26,15 +21,16 @@ class XorpRtrmgr(CoreService):
|
|||
_configs = ("/etc/xorp/config.boot",)
|
||||
_startindex = 35
|
||||
_startup = ("xorp_rtrmgr -d -b %s -l /var/log/%s.log -P /var/run/%s.pid" % (_configs[0], _name, _name),)
|
||||
_shutdown = ("killall xorp_rtrmgr", )
|
||||
_validate = ("pidof xorp_rtrmgr", )
|
||||
_shutdown = ("killall xorp_rtrmgr",)
|
||||
_validate = ("pidof xorp_rtrmgr",)
|
||||
|
||||
@classmethod
|
||||
def generateconfig(cls, node, filename, services):
|
||||
''' Returns config.boot configuration file text. Other services that
|
||||
depend on this will have generatexorpconfig() hooks that are
|
||||
"""
|
||||
Returns config.boot configuration file text. Other services that
|
||||
depend on this will have generatexorpconfig() hooks that are
|
||||
invoked here. Filename currently ignored.
|
||||
'''
|
||||
"""
|
||||
cfg = "interfaces {\n"
|
||||
for ifc in node.netifs():
|
||||
cfg += " interface %s {\n" % ifc.name
|
||||
|
@ -50,40 +46,40 @@ class XorpRtrmgr(CoreService):
|
|||
s._depends.index(cls._name)
|
||||
cfg += s.generatexorpconfig(node)
|
||||
except ValueError:
|
||||
pass
|
||||
logger.exception("error getting value from service: %s", cls._name)
|
||||
|
||||
return cfg
|
||||
|
||||
|
||||
@staticmethod
|
||||
def addrstr(x):
|
||||
''' helper for mapping IP addresses to XORP config statements
|
||||
'''
|
||||
try:
|
||||
(addr, plen) = x.split("/")
|
||||
except Exception:
|
||||
raise ValueError, "invalid address"
|
||||
"""
|
||||
helper for mapping IP addresses to XORP config statements
|
||||
"""
|
||||
addr, plen = x.split("/")
|
||||
cfg = "\t address %s {\n" % addr
|
||||
cfg += "\t\tprefix-length: %s\n" % plen
|
||||
cfg +="\t }\n"
|
||||
cfg += "\t }\n"
|
||||
return cfg
|
||||
|
||||
|
||||
@staticmethod
|
||||
def lladdrstr(ifc):
|
||||
''' helper for adding link-local address entries (required by OSPFv3)
|
||||
'''
|
||||
"""
|
||||
helper for adding link-local address entries (required by OSPFv3)
|
||||
"""
|
||||
cfg = "\t address %s {\n" % ifc.hwaddr.tolinklocal()
|
||||
cfg += "\t\tprefix-length: 64\n"
|
||||
cfg += "\t }\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpRtrmgr)
|
||||
|
||||
|
||||
class XorpService(CoreService):
|
||||
''' Parent class for XORP services. Defines properties and methods
|
||||
common to XORP's routing daemons.
|
||||
'''
|
||||
"""
|
||||
Parent class for XORP services. Defines properties and methods
|
||||
common to XORP's routing daemons.
|
||||
"""
|
||||
_name = "XorpDaemon"
|
||||
_group = "XORP"
|
||||
_depends = ("xorp_rtrmgr", )
|
||||
_depends = ("xorp_rtrmgr",)
|
||||
_dirs = ()
|
||||
_configs = ()
|
||||
_startindex = 40
|
||||
|
@ -93,22 +89,24 @@ class XorpService(CoreService):
|
|||
|
||||
@staticmethod
|
||||
def fea(forwarding):
|
||||
''' Helper to add a forwarding engine entry to the config file.
|
||||
'''
|
||||
"""
|
||||
Helper to add a forwarding engine entry to the config file.
|
||||
"""
|
||||
cfg = "fea {\n"
|
||||
cfg += " %s {\n" % forwarding
|
||||
cfg += "\tdisable:false\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
|
||||
@staticmethod
|
||||
def mfea(forwarding, ifcs):
|
||||
''' Helper to add a multicast forwarding engine entry to the config file.
|
||||
'''
|
||||
"""
|
||||
Helper to add a multicast forwarding engine entry to the config file.
|
||||
"""
|
||||
names = []
|
||||
for ifc in ifcs:
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
names.append(ifc.name)
|
||||
names.append("register_vif")
|
||||
|
@ -125,11 +123,11 @@ class XorpService(CoreService):
|
|||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
|
||||
@staticmethod
|
||||
def policyexportconnected():
|
||||
''' Helper to add a policy statement for exporting connected routes.
|
||||
'''
|
||||
"""
|
||||
Helper to add a policy statement for exporting connected routes.
|
||||
"""
|
||||
cfg = "policy {\n"
|
||||
cfg += " policy-statement export-connected {\n"
|
||||
cfg += "\tterm 100 {\n"
|
||||
|
@ -143,34 +141,37 @@ class XorpService(CoreService):
|
|||
|
||||
@staticmethod
|
||||
def routerid(node):
|
||||
''' Helper to return the first IPv4 address of a node as its router ID.
|
||||
'''
|
||||
"""
|
||||
Helper to return the first IPv4 address of a node as its router ID.
|
||||
"""
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
for a in ifc.addrlist:
|
||||
if a.find(".") >= 0:
|
||||
return a.split('/')[0]
|
||||
#raise ValueError, "no IPv4 address found for router ID"
|
||||
return a.split('/')[0]
|
||||
# raise ValueError, "no IPv4 address found for router ID"
|
||||
return "0.0.0.0"
|
||||
|
||||
@classmethod
|
||||
def generateconfig(cls, node, filename, services):
|
||||
def generateconfig(cls, node, filename, services):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
return ""
|
||||
|
||||
|
||||
class XorpOspfv2(XorpService):
|
||||
''' The OSPFv2 service provides IPv4 routing for wired networks. It does
|
||||
not build its own configuration file but has hooks for adding to the
|
||||
unified XORP configuration file.
|
||||
'''
|
||||
"""
|
||||
The OSPFv2 service provides IPv4 routing for wired networks. It does
|
||||
not build its own configuration file but has hooks for adding to the
|
||||
unified XORP configuration file.
|
||||
"""
|
||||
_name = "XORP_OSPFv2"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.fea("unicast-forwarding4")
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += "\nprotocols {\n"
|
||||
|
@ -178,7 +179,7 @@ class XorpOspfv2(XorpService):
|
|||
cfg += "\trouter-id: %s\n" % rtrid
|
||||
cfg += "\tarea 0.0.0.0 {\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
cfg += "\t interface %s {\n" % ifc.name
|
||||
cfg += "\t\tvif %s {\n" % ifc.name
|
||||
|
@ -194,18 +195,18 @@ class XorpOspfv2(XorpService):
|
|||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpOspfv2)
|
||||
|
||||
|
||||
class XorpOspfv3(XorpService):
|
||||
''' The OSPFv3 service provides IPv6 routing. It does
|
||||
not build its own configuration file but has hooks for adding to the
|
||||
unified XORP configuration file.
|
||||
'''
|
||||
"""
|
||||
The OSPFv3 service provides IPv6 routing. It does
|
||||
not build its own configuration file but has hooks for adding to the
|
||||
unified XORP configuration file.
|
||||
"""
|
||||
_name = "XORP_OSPFv3"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.fea("unicast-forwarding6")
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += "\nprotocols {\n"
|
||||
|
@ -213,7 +214,7 @@ class XorpOspfv3(XorpService):
|
|||
cfg += "\trouter-id: %s\n" % rtrid
|
||||
cfg += "\tarea 0.0.0.0 {\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
cfg += "\t interface %s {\n" % ifc.name
|
||||
cfg += "\t\tvif %s {\n" % ifc.name
|
||||
|
@ -223,15 +224,15 @@ class XorpOspfv3(XorpService):
|
|||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpOspfv3)
|
||||
|
||||
|
||||
class XorpBgp(XorpService):
|
||||
''' IPv4 inter-domain routing. AS numbers and peers must be customized.
|
||||
'''
|
||||
"""
|
||||
IPv4 inter-domain routing. AS numbers and peers must be customized.
|
||||
"""
|
||||
_name = "XORP_BGP"
|
||||
_custom_needed = True
|
||||
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = "/* This is a sample config that should be customized with\n"
|
||||
|
@ -253,22 +254,23 @@ class XorpBgp(XorpService):
|
|||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpBgp)
|
||||
|
||||
class XorpRip(XorpService):
|
||||
''' RIP IPv4 unicast routing.
|
||||
'''
|
||||
"""
|
||||
RIP IPv4 unicast routing.
|
||||
"""
|
||||
|
||||
_name = "XORP_RIP"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.fea("unicast-forwarding4")
|
||||
cfg += cls.policyexportconnected()
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " rip {\n"
|
||||
cfg += "\texport: \"export-connected\"\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
|
@ -284,68 +286,68 @@ class XorpRip(XorpService):
|
|||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpRip)
|
||||
|
||||
|
||||
class XorpRipng(XorpService):
|
||||
''' RIP NG IPv6 unicast routing.
|
||||
'''
|
||||
"""
|
||||
RIP NG IPv6 unicast routing.
|
||||
"""
|
||||
_name = "XORP_RIPNG"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.fea("unicast-forwarding6")
|
||||
cfg += cls.policyexportconnected()
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " ripng {\n"
|
||||
cfg += "\texport: \"export-connected\"\n"
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
# for a in ifc.addrlist:
|
||||
# if a.find(":") < 0:
|
||||
# continue
|
||||
# addr = a.split("/")[0]
|
||||
# cfg += "\t\taddress %s {\n" % addr
|
||||
# cfg += "\t\t disable: false\n"
|
||||
# cfg += "\t\t}\n"
|
||||
# for a in ifc.addrlist:
|
||||
# if a.find(":") < 0:
|
||||
# continue
|
||||
# addr = a.split("/")[0]
|
||||
# cfg += "\t\taddress %s {\n" % addr
|
||||
# cfg += "\t\t disable: false\n"
|
||||
# cfg += "\t\t}\n"
|
||||
cfg += "\t\taddress %s {\n" % ifc.hwaddr.tolinklocal()
|
||||
cfg += "\t\t disable: false\n"
|
||||
cfg += "\t\t}\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
cfg += "\t}\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpRipng)
|
||||
|
||||
|
||||
class XorpPimSm4(XorpService):
|
||||
''' PIM Sparse Mode IPv4 multicast routing.
|
||||
'''
|
||||
"""
|
||||
PIM Sparse Mode IPv4 multicast routing.
|
||||
"""
|
||||
_name = "XORP_PIMSM4"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.mfea("mfea4", node.netifs())
|
||||
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " igmp {\n"
|
||||
names = []
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
names.append(ifc.name)
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
cfg += "\t\tdisable: false\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
cfg += "\t}\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " pimsm4 {\n"
|
||||
|
||||
|
@ -368,46 +370,46 @@ class XorpPimSm4(XorpService):
|
|||
cfg += "\t\t}\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
|
||||
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " fib2mrib {\n"
|
||||
cfg += "\tdisable: false\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpPimSm4)
|
||||
|
||||
|
||||
class XorpPimSm6(XorpService):
|
||||
''' PIM Sparse Mode IPv6 multicast routing.
|
||||
'''
|
||||
"""
|
||||
PIM Sparse Mode IPv6 multicast routing.
|
||||
"""
|
||||
_name = "XORP_PIMSM6"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.mfea("mfea6", node.netifs())
|
||||
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " mld {\n"
|
||||
names = []
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
names.append(ifc.name)
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
cfg += "\t\tdisable: false\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
cfg += "\t}\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " pimsm6 {\n"
|
||||
|
||||
|
||||
names.append("register_vif")
|
||||
for name in names:
|
||||
cfg += "\tinterface %s {\n" % name
|
||||
|
@ -427,33 +429,33 @@ class XorpPimSm6(XorpService):
|
|||
cfg += "\t\t}\n"
|
||||
cfg += "\t }\n"
|
||||
cfg += "\t}\n"
|
||||
|
||||
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
|
||||
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " fib2mrib {\n"
|
||||
cfg += "\tdisable: false\n"
|
||||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpPimSm6)
|
||||
|
||||
|
||||
class XorpOlsr(XorpService):
|
||||
''' OLSR IPv4 unicast MANET routing.
|
||||
'''
|
||||
"""
|
||||
OLSR IPv4 unicast MANET routing.
|
||||
"""
|
||||
_name = "XORP_OLSR"
|
||||
|
||||
@classmethod
|
||||
def generatexorpconfig(cls, node):
|
||||
def generatexorpconfig(cls, node):
|
||||
cfg = cls.fea("unicast-forwarding4")
|
||||
rtrid = cls.routerid(node)
|
||||
cfg += "\nprotocols {\n"
|
||||
cfg += " olsr4 {\n"
|
||||
cfg += "\tmain-address: %s\n" % rtrid
|
||||
for ifc in node.netifs():
|
||||
if hasattr(ifc, 'control') and ifc.control == True:
|
||||
if hasattr(ifc, 'control') and ifc.control is True:
|
||||
continue
|
||||
cfg += "\tinterface %s {\n" % ifc.name
|
||||
cfg += "\t vif %s {\n" % ifc.name
|
||||
|
@ -468,5 +470,15 @@ class XorpOlsr(XorpService):
|
|||
cfg += " }\n"
|
||||
cfg += "}\n"
|
||||
return cfg
|
||||
|
||||
addservice(XorpOlsr)
|
||||
|
||||
|
||||
def load_services():
|
||||
ServiceManager.add(XorpRtrmgr)
|
||||
ServiceManager.add(XorpOspfv2)
|
||||
ServiceManager.add(XorpOspfv3)
|
||||
ServiceManager.add(XorpBgp)
|
||||
ServiceManager.add(XorpRip)
|
||||
ServiceManager.add(XorpRipng)
|
||||
ServiceManager.add(XorpPimSm4)
|
||||
ServiceManager.add(XorpPimSm6)
|
||||
ServiceManager.add(XorpOlsr)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue