2017-04-25 16:45:34 +01:00
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
bird.py: defines routing services provided by the BIRD Internet Routing Daemon.
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2017-04-25 16:45:34 +01:00
|
|
|
from core.service import CoreService
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
class Bird(CoreService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
Bird router support
|
|
|
|
"""
|
2018-06-15 22:03:27 +01:00
|
|
|
name = "bird"
|
2018-06-19 17:19:49 +01:00
|
|
|
executables = ("bird",)
|
2018-06-15 22:03:27 +01:00
|
|
|
group = "BIRD"
|
|
|
|
dirs = ("/etc/bird",)
|
|
|
|
configs = ("/etc/bird/bird.conf",)
|
|
|
|
startup = ("bird -c %s" % (configs[0]),)
|
|
|
|
shutdown = ("killall bird",)
|
|
|
|
validate = ("pidof bird",)
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2018-06-22 23:47:02 +01:00
|
|
|
def generate_config(cls, node, filename):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
Return the bird.conf file contents.
|
|
|
|
"""
|
2018-06-15 22:03:27 +01:00
|
|
|
if filename == cls.configs[0]:
|
2018-06-21 22:56:30 +01:00
|
|
|
return cls.generateBirdConf(node)
|
2013-08-29 15:21:13 +01:00
|
|
|
else:
|
|
|
|
raise ValueError
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def routerid(node):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
Helper to return the first IPv4 address of a node as its router ID.
|
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
for ifc in node.netifs():
|
2018-06-15 22:03:27 +01:00
|
|
|
if hasattr(ifc, 'control') and ifc.control is True:
|
2013-08-29 15:21:13 +01:00
|
|
|
continue
|
|
|
|
for a in ifc.addrlist:
|
|
|
|
if a.find(".") >= 0:
|
2017-04-25 16:45:34 +01:00
|
|
|
return a.split('/')[0]
|
|
|
|
# raise ValueError, "no IPv4 address found for router ID"
|
2013-08-29 15:21:13 +01:00
|
|
|
return "0.0.0.0"
|
|
|
|
|
|
|
|
@classmethod
|
2018-06-21 22:56:30 +01:00
|
|
|
def generateBirdConf(cls, node):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
Returns configuration file text. Other services that depend on bird
|
|
|
|
will have generatebirdifcconfig() and generatebirdconfig()
|
|
|
|
hooks that are invoked here.
|
|
|
|
"""
|
|
|
|
cfg = """\
|
2013-08-29 15:21:13 +01:00
|
|
|
/* Main configuration file for BIRD. This is ony a template,
|
|
|
|
* you will *need* to customize it according to your needs
|
|
|
|
* Beware that only double quotes \'"\' are valid. No singles. */
|
2017-04-25 16:45:34 +01:00
|
|
|
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
log "/var/log/%s.log" all;
|
|
|
|
#debug protocols all;
|
|
|
|
#debug commands 2;
|
|
|
|
|
|
|
|
router id %s; # Mandatory for IPv6, may be automatic for IPv4
|
|
|
|
|
|
|
|
protocol kernel {
|
|
|
|
persist; # Don\'t remove routes on BIRD shutdown
|
|
|
|
scan time 200; # Scan kernel routing table every 200 seconds
|
|
|
|
export all;
|
|
|
|
import all;
|
|
|
|
}
|
|
|
|
|
|
|
|
protocol device {
|
|
|
|
scan time 10; # Scan interfaces every 10 seconds
|
|
|
|
}
|
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
""" % (cls.name, cls.routerid(node))
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
# Generate protocol specific configurations
|
2018-06-21 22:56:30 +01:00
|
|
|
for s in node.services:
|
2018-06-22 16:16:59 +01:00
|
|
|
if cls.name not in s.dependencies:
|
2013-08-29 15:21:13 +01:00
|
|
|
continue
|
|
|
|
cfg += s.generatebirdconfig(node)
|
|
|
|
|
|
|
|
return cfg
|
|
|
|
|
2017-04-25 16:45:34 +01:00
|
|
|
|
2013-08-29 15:21:13 +01:00
|
|
|
class BirdService(CoreService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
Parent class for Bird services. Defines properties and methods
|
2013-08-29 15:21:13 +01:00
|
|
|
common to Bird's routing daemons.
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
name = None
|
2018-06-19 17:19:49 +01:00
|
|
|
executables = ("bird",)
|
2018-06-15 22:03:27 +01:00
|
|
|
group = "BIRD"
|
2018-06-21 19:20:08 +01:00
|
|
|
dependencies = ("bird",)
|
2018-06-15 22:03:27 +01:00
|
|
|
dirs = ()
|
|
|
|
configs = ()
|
|
|
|
startup = ()
|
|
|
|
shutdown = ()
|
|
|
|
meta = "The config file for this service can be found in the bird service."
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2017-04-25 16:45:34 +01:00
|
|
|
def generatebirdconfig(cls, node):
|
2013-08-29 15:21:13 +01:00
|
|
|
return ""
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def generatebirdifcconfig(cls, node):
|
2018-06-15 22:03:27 +01:00
|
|
|
"""
|
|
|
|
Use only bare interfaces descriptions in generated protocol
|
2013-08-29 15:21:13 +01:00
|
|
|
configurations. This has the slight advantage of being the same
|
|
|
|
everywhere.
|
2018-06-15 22:03:27 +01:00
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg = ""
|
|
|
|
|
|
|
|
for ifc in node.netifs():
|
2018-06-15 22:03:27 +01:00
|
|
|
if hasattr(ifc, 'control') and ifc.control is True:
|
2017-04-25 16:45:34 +01:00
|
|
|
continue
|
|
|
|
cfg += ' interface "%s";\n' % ifc.name
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
return cfg
|
|
|
|
|
|
|
|
|
|
|
|
class BirdBgp(BirdService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
BGP BIRD Service (configuration generation)
|
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
name = "BIRD_BGP"
|
|
|
|
custom_needed = True
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2017-04-25 16:45:34 +01:00
|
|
|
def generatebirdconfig(cls, node):
|
2013-08-29 15:21:13 +01:00
|
|
|
return """
|
|
|
|
/* This is a sample config that should be customized with appropriate AS numbers
|
|
|
|
* and peers; add one section like this for each neighbor */
|
|
|
|
|
|
|
|
protocol bgp {
|
|
|
|
local as 65000; # Customize your AS number
|
|
|
|
neighbor 198.51.100.130 as 64496; # Customize neighbor AS number && IP
|
|
|
|
export filter { # We use non-trivial export rules
|
|
|
|
# This is an example. You should advertise only *your routes*
|
|
|
|
if (source = RTS_DEVICE) || (source = RTS_OSPF) then {
|
|
|
|
# bgp_community.add((65000,64501)); # Assign our community
|
|
|
|
accept;
|
|
|
|
}
|
|
|
|
reject;
|
|
|
|
};
|
|
|
|
import all;
|
|
|
|
}
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2017-04-25 16:45:34 +01:00
|
|
|
|
2013-08-29 15:21:13 +01:00
|
|
|
class BirdOspf(BirdService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
OSPF BIRD Service (configuration generation)
|
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
name = "BIRD_OSPFv2"
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2017-04-25 16:45:34 +01:00
|
|
|
def generatebirdconfig(cls, node):
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg = 'protocol ospf {\n'
|
|
|
|
cfg += ' export filter {\n'
|
|
|
|
cfg += ' if source = RTS_BGP then {\n'
|
|
|
|
cfg += ' ospf_metric1 = 100;\n'
|
|
|
|
cfg += ' accept;\n'
|
|
|
|
cfg += ' }\n'
|
|
|
|
cfg += ' accept;\n'
|
|
|
|
cfg += ' };\n'
|
|
|
|
cfg += ' area 0.0.0.0 {\n'
|
2017-04-25 16:45:34 +01:00
|
|
|
cfg += cls.generatebirdifcconfig(node)
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg += ' };\n'
|
|
|
|
cfg += '}\n\n'
|
|
|
|
|
|
|
|
return cfg
|
|
|
|
|
|
|
|
|
|
|
|
class BirdRadv(BirdService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
RADV BIRD Service (configuration generation)
|
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
name = "BIRD_RADV"
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2017-04-25 16:45:34 +01:00
|
|
|
def generatebirdconfig(cls, node):
|
|
|
|
cfg = '/* This is a sample config that must be customized */\n'
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
cfg += 'protocol radv {\n'
|
|
|
|
cfg += ' # auto configuration on all interfaces\n'
|
2017-04-25 16:45:34 +01:00
|
|
|
cfg += cls.generatebirdifcconfig(node)
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg += ' # Advertise DNS\n'
|
|
|
|
cfg += ' rdnss {\n'
|
|
|
|
cfg += '# lifetime mult 10;\n'
|
|
|
|
cfg += '# lifetime mult 10;\n'
|
|
|
|
cfg += '# ns 2001:0DB8:1234::11;\n'
|
|
|
|
cfg += '# ns 2001:0DB8:1234::11;\n'
|
|
|
|
cfg += '# ns 2001:0DB8:1234::12;\n'
|
|
|
|
cfg += '# ns 2001:0DB8:1234::12;\n'
|
|
|
|
cfg += ' };\n'
|
|
|
|
cfg += '}\n\n'
|
|
|
|
|
|
|
|
return cfg
|
|
|
|
|
|
|
|
|
|
|
|
class BirdRip(BirdService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
RIP BIRD Service (configuration generation)
|
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
name = "BIRD_RIP"
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2017-04-25 16:45:34 +01:00
|
|
|
def generatebirdconfig(cls, node):
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg = 'protocol rip {\n'
|
|
|
|
cfg += ' period 10;\n'
|
|
|
|
cfg += ' garbage time 60;\n'
|
2017-04-25 16:45:34 +01:00
|
|
|
cfg += cls.generatebirdifcconfig(node)
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg += ' honor neighbor;\n'
|
|
|
|
cfg += ' authentication none;\n'
|
|
|
|
cfg += ' import all;\n'
|
|
|
|
cfg += ' export all;\n'
|
|
|
|
cfg += '}\n\n'
|
|
|
|
|
|
|
|
return cfg
|
|
|
|
|
|
|
|
|
|
|
|
class BirdStatic(BirdService):
|
2017-04-25 16:45:34 +01:00
|
|
|
"""
|
|
|
|
Static Bird Service (configuration generation)
|
|
|
|
"""
|
2013-08-29 15:21:13 +01:00
|
|
|
|
2018-06-15 22:03:27 +01:00
|
|
|
name = "BIRD_static"
|
|
|
|
custom_needed = True
|
2013-08-29 15:21:13 +01:00
|
|
|
|
|
|
|
@classmethod
|
2017-04-25 16:45:34 +01:00
|
|
|
def generatebirdconfig(cls, node):
|
2013-08-29 15:21:13 +01:00
|
|
|
cfg = '/* This is a sample config that must be customized */\n'
|
|
|
|
cfg += 'protocol static {\n'
|
|
|
|
cfg += '# route 0.0.0.0/0 via 198.51.100.130; # Default route. Do NOT advertise on BGP !\n'
|
|
|
|
cfg += '# route 203.0.113.0/24 reject; # Sink route\n'
|
|
|
|
cfg += '# route 10.2.0.0/24 via "arc0"; # Secondary network\n'
|
|
|
|
cfg += '}\n\n'
|
|
|
|
return cfg
|