diff --git a/examples/bird_exp/__init__.py b/examples/bird_exp/__init__.py new file mode 100644 index 0000000..6198c5c --- /dev/null +++ b/examples/bird_exp/__init__.py @@ -0,0 +1,3 @@ +""" +BIRD IXP Example for MiniNExT +""" diff --git a/examples/bird_exp/configs/a1/bird.conf b/examples/bird_exp/configs/a1/bird.conf new file mode 100755 index 0000000..64cd0b6 --- /dev/null +++ b/examples/bird_exp/configs/a1/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.1.1; + + +protocol kernel { + + persist; # Don't remove routes on bird shutdown + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.1.0:255.255.255.0 via 172.0.1.1; + +} + + + + +protocol bgp { + + description "AS 100"; + local as 100; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.1.1; # What local address we use for the TCP connection + +} + + diff --git a/examples/bird_exp/configs/a1/envvars b/examples/bird_exp/configs/a1/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/bird_exp/configs/a1/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/bird_exp/configs/b1/bird.conf b/examples/bird_exp/configs/b1/bird.conf new file mode 100755 index 0000000..7a39bd7 --- /dev/null +++ b/examples/bird_exp/configs/b1/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.2.1; + + +protocol kernel { + + persist; # Don't remove routes on bird shutdown + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.2.0:255.255.255.0 via 172.0.2.1; + +} + + + + +protocol bgp { + + description "AS 200"; + local as 200; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.2.1; # What local address we use for the TCP connection + +} + + diff --git a/examples/bird_exp/configs/b1/envvars b/examples/bird_exp/configs/b1/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/bird_exp/configs/b1/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/bird_exp/configs/c1/bird.conf b/examples/bird_exp/configs/c1/bird.conf new file mode 100755 index 0000000..6078a28 --- /dev/null +++ b/examples/bird_exp/configs/c1/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.3.2; + + +protocol kernel { + + persist; # Don't remove routes on bird shutdown + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.3.0:255.255.255.0 via 172.0.3.2; + +} + + + + +protocol bgp { + + description "AS 300_1"; + local as 300; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.3.2; # What local address we use for the TCP connection + +} + + diff --git a/examples/bird_exp/configs/c1/envvars b/examples/bird_exp/configs/c1/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/bird_exp/configs/c1/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/bird_exp/configs/c2/bird.conf b/examples/bird_exp/configs/c2/bird.conf new file mode 100755 index 0000000..1d4cbe8 --- /dev/null +++ b/examples/bird_exp/configs/c2/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.3.1; + + +protocol kernel { + + persist; # Don't remove routes on bird shutdown + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.3.0:255.255.255.0 via 172.0.3.1; + +} + + + + +protocol bgp { + + description "AS 300_2"; + local as 300; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.3.1; # What local address we use for the TCP connection + +} + + diff --git a/examples/bird_exp/configs/c2/envvars b/examples/bird_exp/configs/c2/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/bird_exp/configs/c2/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/bird_exp/configs/d1/bird.conf b/examples/bird_exp/configs/d1/bird.conf new file mode 100755 index 0000000..a9f0434 --- /dev/null +++ b/examples/bird_exp/configs/d1/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.4.1; + + +protocol kernel { + + persist; # Don't remove routes on bird shutdown + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.4.0:255.255.255.0 via 172.0.4.1; + +} + + + + +protocol bgp { + + description "AS 400"; + local as 400; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.4.1; # What local address we use for the TCP connection + +} + + diff --git a/examples/bird_exp/configs/d1/envvars b/examples/bird_exp/configs/d1/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/bird_exp/configs/d1/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/bird_exp/configs/rs/bird.conf b/examples/bird_exp/configs/rs/bird.conf new file mode 100755 index 0000000..930f7a3 --- /dev/null +++ b/examples/bird_exp/configs/rs/bird.conf @@ -0,0 +1,139 @@ +router id 172.0.254.254; + +protocol kernel { + + persist; # Don't remove routes on bird shutdown + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol bgp v_0 { + + description "Route Server"; + local as 65000; + neighbor 172.0.1.1 as 100; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; + rs client; # What local address we use for the TCP connection + +} + +protocol bgp v_1 { + + description "Route Server"; + local as 65000; + neighbor 172.0.2.1 as 200; + + export all; + import all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; + rs client; +} + +protocol bgp v_2 { + + description "Route Server"; + local as 65000; + neighbor 172.0.3.1 as 300; + export all; + import all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; +rs client; +} + +protocol bgp v_3 { + + description "Route Server"; + local as 65000; + neighbor 172.0.3.2 as 300; + export all; + import all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; +rs client; +} + +protocol bgp v_4 { + + description "Route Server"; + local as 65000; + neighbor 172.0.4.1 as 400; + export all; + import all; + + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; + rs client; +} + + + diff --git a/examples/bird_exp/configs/rs/envvars b/examples/bird_exp/configs/rs/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/bird_exp/configs/rs/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/bird_exp/start.py b/examples/bird_exp/start.py new file mode 100755 index 0000000..8054252 --- /dev/null +++ b/examples/bird_exp/start.py @@ -0,0 +1,67 @@ +#!/usr/bin/python + +""" +Example network of Bird routers +(BirdTopo + BirdService) +""" + +import sys +import atexit + +# patch isShellBuiltin +import mininet.util +import mininext.util +mininet.util.isShellBuiltin = mininext.util.isShellBuiltin +sys.modules['mininet.util'] = mininet.util + +from mininet.util import dumpNodeConnections +from mininet.node import OVSController +from mininet.log import setLogLevel, info + +from mininext.cli import CLI +from mininext.net import MiniNExT + +from topo import BirdTopo + +net = None + + +def startNetwork(): + "instantiates a topo, then starts the network and prints debug information" + + info('** Creating Bird network topology\n') + topo = BirdTopo() + + info('** Starting the network\n') + global net + net = MiniNExT(topo, controller=OVSController) + net.start() + + info('** Dumping host connections\n') + dumpNodeConnections(net.hosts) + + info('** Testing network connectivity\n') + net.ping(net.hosts) + + info('** Dumping host processes\n') + for host in net.hosts: + host.cmdPrint("ps aux") + + info('** Running CLI\n') + CLI(net) + + +def stopNetwork(): + "stops a network (only called on a forced cleanup)" + + if net is not None: + info('** Tearing down Bird network\n') + net.stop() + +if __name__ == '__main__': + # Force cleanup on exit by registering a cleanup function + atexit.register(stopNetwork) + + # Tell mininet to print useful information + setLogLevel('info') + startNetwork() diff --git a/examples/bird_exp/topo.py b/examples/bird_exp/topo.py new file mode 100644 index 0000000..89847c7 --- /dev/null +++ b/examples/bird_exp/topo.py @@ -0,0 +1,77 @@ +""" +Example topology of Bird routers +""" + +import inspect +import os +from mininext.topo import Topo +from mininext.services.bird import BirdService + +from collections import namedtuple + +BirdHost = namedtuple("BirdHost", "name ip loIP") +net = None + + +class BirdTopo(Topo): + + "Creates a topology of Bird routers" + + def __init__(self): + """Initialize a Bird topology with 5 routers, configure their IP + addresses, loop back interfaces, and paths to their private + configuration directories.""" + Topo.__init__(self) + + # Directory where this file / script is located" + selfPath = os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) # script directory + + # Initialize a service helper for Bird with default options + BirdSvc = BirdService(autoStop=False) + + # Path configurations for mounts + BirdBaseConfigPath = selfPath + '/configs/' + + # List of Bird host configs + BirdHosts = [] + BirdHosts.append(BirdHost(name='a1', ip='172.0.1.1/16', + loIP='10.0.1.1/24')) + BirdHosts.append(BirdHost(name='b1', ip='172.0.2.1/16', + loIP='10.0.2.1/24')) + BirdHosts.append(BirdHost(name='c1', ip='172.0.3.2/16', + loIP='10.0.3.1/24')) + BirdHosts.append(BirdHost(name='c2', ip='172.0.3.1/16', + loIP='10.0.3.1/24')) + BirdHosts.append(BirdHost(name='d1', ip='172.0.4.1/16', + loIP='10.0.4.1/24')) + BirdHosts.append(BirdHost(name='rs', ip='172.0.254.254/16', + loIP=None)) + + # Add switch for IXP fabric + ixpfabric = self.addSwitch('fabric-sw1') + + # Setup each Bird router, add a link between it and the IXP fabric + for host in BirdHosts: + + # Create an instance of a host, called a BirdContainer + BirdContainer = self.addHost(name=host.name, + ip=host.ip, + hostname=host.name, + privateLogDir=True, + privateRunDir=True, + inMountNamespace=True, + inPIDNamespace=True, + inUTSNamespace=True) + + # Add a loopback interface with an IP in router's announced range + self.addNodeLoopbackIntf(node=host.name, ip=host.loIP) + + # Configure and setup the Bird service for this node + BirdSvcConfig = \ + {'BirdConfigPath': BirdBaseConfigPath + host.name} + self.addNodeService(node=host.name, service=BirdSvc, + nodeConfig=BirdSvcConfig) + + # Attach the BirdContainer to the IXP Fabric Switch + self.addLink(BirdContainer, ixpfabric) diff --git a/examples/bird_exp/topo.pyc b/examples/bird_exp/topo.pyc new file mode 100644 index 0000000..0f59a0a Binary files /dev/null and b/examples/bird_exp/topo.pyc differ diff --git a/examples/peering-ixp/__init__.py b/examples/peering-ixp/__init__.py new file mode 100644 index 0000000..5dd90ff --- /dev/null +++ b/examples/peering-ixp/__init__.py @@ -0,0 +1,3 @@ +""" +Quagga IXP Example for MiniNExT +""" diff --git a/examples/peering-ixp/configs/Client1/bird.conf b/examples/peering-ixp/configs/Client1/bird.conf new file mode 100755 index 0000000..b586b18 --- /dev/null +++ b/examples/peering-ixp/configs/Client1/bird.conf @@ -0,0 +1,48 @@ +router id 192.168.1.2; + + +protocol kernel { + + + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.3.0:255.255.255.0 via 192.168.1.2; + +} + + + + +protocol bgp { + + description "AS 65550"; + local as 65550; + neighbor 192.168.1.4 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 192.168.1.2; # What local address we use for the TCP connection + +} + + diff --git a/examples/peering-ixp/configs/Client1/envvars b/examples/peering-ixp/configs/Client1/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/peering-ixp/configs/Client1/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/peering-ixp/configs/Client2/bird.conf b/examples/peering-ixp/configs/Client2/bird.conf new file mode 100755 index 0000000..ac959b4 --- /dev/null +++ b/examples/peering-ixp/configs/Client2/bird.conf @@ -0,0 +1,48 @@ +router id 192.168.1.3; + + +protocol kernel { + + + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.4.0:255.255.255.0 via 192.168.1.3; + +} + + + + +protocol bgp { + + description "AS 65560"; + local as 65560; + neighbor 192.168.1.4 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 192.168.1.3; # What local address we use for the TCP connection + +} + + diff --git a/examples/peering-ixp/configs/Client2/envvars b/examples/peering-ixp/configs/Client2/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/peering-ixp/configs/Client2/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/peering-ixp/configs/Peer1/bird.conf b/examples/peering-ixp/configs/Peer1/bird.conf new file mode 100755 index 0000000..5b14657 --- /dev/null +++ b/examples/peering-ixp/configs/Peer1/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.1.1; + + +protocol kernel { + + + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.1.0:255.255.255.0 via 172.0.1.1; + +} + + + + +protocol bgp { + + description "AS 100"; + local as 100; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.1.1; # What local address we use for the TCP connection + +} + + diff --git a/examples/peering-ixp/configs/Peer1/envvars b/examples/peering-ixp/configs/Peer1/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/peering-ixp/configs/Peer1/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/peering-ixp/configs/Peer2/bird.conf b/examples/peering-ixp/configs/Peer2/bird.conf new file mode 100755 index 0000000..fb44e8c --- /dev/null +++ b/examples/peering-ixp/configs/Peer2/bird.conf @@ -0,0 +1,48 @@ +router id 172.0.2.1; + + +protocol kernel { + + + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none + +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol static { + + route 10.0.2.0:255.255.255.0 via 172.0.2.1; + +} + + + + +protocol bgp { + + description "AS 200"; + local as 200; + neighbor 172.0.254.254 as 65000; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + source address 172.0.2.1; # What local address we use for the TCP connection + +} + + diff --git a/examples/peering-ixp/configs/Peer2/envvars b/examples/peering-ixp/configs/Peer2/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/peering-ixp/configs/Peer2/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/peering-ixp/configs/rs/bird.conf b/examples/peering-ixp/configs/rs/bird.conf new file mode 100755 index 0000000..70ecf80 --- /dev/null +++ b/examples/peering-ixp/configs/rs/bird.conf @@ -0,0 +1,116 @@ + + +protocol kernel { + + + scan time 20; # Scan kernel routing table every 20 seconds + import all; + export all; # Default is export none +} + + +protocol device { + scan time 10; # Scan interfaces every 10 seconds +} + + +protocol bgp v_0 { + + description "Route Server"; + local as 65000; + neighbor 172.0.1.1 as 100; + import all; + export all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; + rs client; # What local address we use for the TCP connection + +} + +protocol bgp v_1 { + + description "Route Server"; + local as 65000; + neighbor 172.0.2.1 as 200; + + export all; + import all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 172.0.254.254; + rs client; +} + +protocol bgp v_2 { + + description "Route Server"; + local as 65000; + neighbor 192.168.1.2 as 65550; + export all; + import all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 192.168.1.4; +rs client; +} + +protocol bgp v_3 { + + description "Route Server"; + local as 65000; + neighbor 192.168.1.3 as 65560; + export all; + import all; + hold time 240; + startup hold time 240; + connect retry time 120; + keepalive time 80; # defaults to hold time / 3 + start delay time 5; # How long do we wait before initial connect + error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive + + error forget time 300; # ... until this timeout expires) + disable after error; # Disable the protocol automatically when an error occurs + path metric 1; # Prefer routes with shorter paths (like Cisco does) + default bgp_med 0; # MED value we use for comparison when none is defined + default bgp_local_pref 0; # The same for local preference + source address 192.168.1.4; +rs client; +} + + + + diff --git a/examples/peering-ixp/configs/rs/envvars b/examples/peering-ixp/configs/rs/envvars new file mode 100755 index 0000000..9ca9baa --- /dev/null +++ b/examples/peering-ixp/configs/rs/envvars @@ -0,0 +1,3 @@ +BIRD_RUN_USER=bird +BIRD_RUN_GROUP=bird +#BIRD_ARGS= diff --git a/examples/peering-ixp/start.py b/examples/peering-ixp/start.py new file mode 100755 index 0000000..cce2e02 --- /dev/null +++ b/examples/peering-ixp/start.py @@ -0,0 +1,73 @@ +#!/usr/bin/python + +""" +Example network of Bird routers +(BirdTopo + BirdService) +""" + +import sys +import atexit + +# patch isShellBuiltin +import mininet.util +import mininext.util +mininet.util.isShellBuiltin = mininext.util.isShellBuiltin +sys.modules['mininet.util'] = mininet.util + +from mininet.util import dumpNodeConnections +from mininet.node import OVSController +from mininet.log import setLogLevel, info + +from mininext.cli import CLI +from mininext.net import MiniNExT + +from topo import BirdTopo + +net = None + + +def startNetwork(): + "instantiates a topo, then starts the network and prints debug information" + + info('** Creating Bird network topology\n') + topo = BirdTopo() + + info('** Starting the network\n') + global net + net = MiniNExT(topo, controller=OVSController) + net.start() + + info('** Dumping host connections\n') + dumpNodeConnections(net.hosts) + + info('** Testing network connectivity\n') + net.ping(net.hosts) + + info('** Dumping host processes\n') + for host in net.hosts: + host.cmdPrint("ps aux") + + if host.name == "rs": + host.cmd('ifconfig rs-eth1 192.168.1.4 netmask 255.255.255.0') + host.cmd('sysctl -w net.ipv4.ip_forward=1') + host.cmd('sysctl -p /etc/sysctl.conf') + host.cmd('/etc/init.d/procps restart') + + info('** Running CLI\n') + CLI(net) + + +def stopNetwork(): + "stops a network (only called on a forced cleanup)" + + if net is not None: + info('** Tearing down Bird network\n') + net.stop() + +if __name__ == '__main__': + # Force cleanup on exit by registering a cleanup function + atexit.register(stopNetwork) + + # Tell mininet to print useful information + setLogLevel('info') + startNetwork() diff --git a/examples/peering-ixp/topo.py b/examples/peering-ixp/topo.py new file mode 100644 index 0000000..8c1d03d --- /dev/null +++ b/examples/peering-ixp/topo.py @@ -0,0 +1,128 @@ +""" +Example topology of Bird routers +""" + +import inspect +import os +from mininext.topo import Topo +from mininext.services.bird import BirdService +from mininet.net import Mininet +from collections import namedtuple + +BirdHost = namedtuple("BirdHost", "name ip loIP") +net = None + + +class BirdTopo(Topo): + + "Creates a topology of Bird routers" + + def __init__(self): + """Initialize a Bird topology with 5 routers, configure their IP + addresses, loop back interfaces, and paths to their private + configuration directories.""" + Topo.__init__(self) + + # Directory where this file / script is located" + selfPath = os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) # script directory + + # Initialize a service helper for Bird with default options + BirdSvc = BirdService(autoStop=False) + + # Path configurations for mounts + BirdBaseConfigPath = selfPath + '/configs/' + + # List of Bird host configs + BirdHosts = [] + BirdClient = [] + BirdRS = [] + BirdHosts.append(BirdHost(name='Peer1', ip='172.0.1.1/16', + loIP='10.0.1.1/24')) + BirdHosts.append(BirdHost(name='Peer2', ip='172.0.2.1/16', + loIP='10.0.2.1/24')) + BirdClient.append(BirdHost(name='Client1', ip='192.168.1.2/24', + loIP='10.0.3.1/24')) + BirdClient.append(BirdHost(name='Client2', ip='192.168.1.3/24', + loIP='10.0.4.1/24')) + BirdRS.append(BirdHost(name='rs', ip='172.0.254.254/16',loIP=None)) + + # Add switch for IXP fabric + ixpfabric = self.addSwitch('fabric-sw1') + clientsw = self.addSwitch('fabric-sw2') + # Setup each Bird router, add a link between it and the IXP fabric + for host in BirdHosts: + + # Create an instance of a host, called a BirdContainer + BirdContainer = self.addHost(name=host.name, + ip=host.ip, + + hostname=host.name, + privateLogDir=True, + privateRunDir=True, + inMountNamespace=True, + inPIDNamespace=True, + inUTSNamespace=True) + + # Add a loopback interface with an IP in router's announced range + self.addNodeLoopbackIntf(node=host.name, ip=host.loIP) + + # Configure and setup the Bird service for this node + BirdSvcConfig = \ + {'BirdConfigPath': BirdBaseConfigPath + host.name} + self.addNodeService(node=host.name, service=BirdSvc, + nodeConfig=BirdSvcConfig) + + # Attach the BirdContainer to the IXP Fabric Switch + self.addLink(BirdContainer, ixpfabric) + + for host in BirdClient: + + # Create an instance of a host, called a BirdContainer + BirdClientContainer = self.addHost(name=host.name, + ip=host.ip, + + hostname=host.name, + privateLogDir=True, + privateRunDir=True, + inMountNamespace=True, + inPIDNamespace=True, + inUTSNamespace=True) + + # Add a loopback interface with an IP in router's announced range + # Add a loopback interface with an IP in router's announced range + self.addNodeLoopbackIntf(node=host.name, ip=host.loIP) + + # Configure and setup the Bird service for this node + BirdSvcConfig = \ + {'BirdConfigPath': BirdBaseConfigPath + host.name} + self.addNodeService(node=host.name, service=BirdSvc, + nodeConfig=BirdSvcConfig) + + # Attach the BirdContainer to the IXP Fabric Switch + self.addLink(BirdClientContainer, clientsw) + + + BirdRSContainer = self.addHost(name='rs', + ip='172.0.254.254/16', + + hostname='rs', + privateLogDir=True, + privateRunDir=True, + inMountNamespace=True, + inPIDNamespace=True, + inUTSNamespace=True) + + + + + # Configure and setup the Bird service for this node + BirdSvcConfig = \ + {'BirdConfigPath': BirdBaseConfigPath + 'rs'} + + self.addNodeService(node='rs', service=BirdSvc, + nodeConfig=BirdSvcConfig) + + + self.addLink(BirdRSContainer, ixpfabric) + self.addLink(BirdRSContainer, clientsw) diff --git a/examples/peering-ixp/topo.pyc b/examples/peering-ixp/topo.pyc new file mode 100644 index 0000000..b44d63a Binary files /dev/null and b/examples/peering-ixp/topo.pyc differ diff --git a/mininext/services/bird.py b/mininext/services/bird.py new file mode 100644 index 0000000..e975df2 --- /dev/null +++ b/mininext/services/bird.py @@ -0,0 +1,96 @@ +""" +Example service that manages Bird routers +""" + +from mininext.mount import MountProperties, ObjectPermissions, PathProperties +from mininext.moduledeps import serviceCheck +from mininext.service import Service + + +class BirdService(Service): + + "Manages Bird Software Router Service" + + def __init__(self, name="Bird", **params): + """Initializes a BirdService instance with a set of global parameters + + Args: + name (str): Service name (derived class may wish to override) + params: Arbitrary length list of global properties for this service + + """ + + # Verify that Bird is installed" + #serviceCheck('Bird', moduleName='Bird (nongnu.org/Bird/)') + + # Call service initialization (will set defaultGlobalParams) + Service.__init__(self, name=name, **params) + + self.getDefaultGlobalMounts() + + def verifyNodeMeetsServiceRequirements(self, node): + """Verifies that a specified node is configured to support Bird + + Overrides the :class:`.Service` default verification method to conduct + checks specific to Bird. This includes checking that the node + has a private log space, a private run space, and is in a PID + namespace + + Args: + node: Node to inspect + + """ + + if node.inPIDNamespace is False: + raise Exception("Bird service requires PID namespace (node %s)\n" + % (node)) + + if node.hasPrivateLogs is False: + raise Exception("Bird service requires private logs (node %s)\n" + % (node)) + + if node.hasPrivateRun is False: + raise Exception("Bird service requires private /run (node %s)\n" + % (node)) + + def setupNodeForService(self, node): + """After mounts and other operations taken care of by Service Helper, + we perform a few last minute tasks here""" + + # Initialize log directory + #_, err, ret = node.pexec("mkdir /var/log/Bird") + #_, err, ret = node.pexec("chown Bird:Bird /var/log/Bird") + + def getDefaultGlobalParams(self): + "Returns the default parameters for this service" + defaults = {'startCmd': '/etc/init.d/bird start', + 'stopCmd': '/etc/init.d/bird stop', + 'autoStart': True, + 'autoStop': True, + 'configPath': None} + return defaults + + def getDefaultGlobalMounts(self): + "Service-wide default mounts for the Bird service" + + mounts = [] + mountConfigPairs = {} + + # Bird configuration paths + BirdConfigPerms = ObjectPermissions(username='bird', + groupname='bird', + mode=0o775, + strictMode=False, + enforceRecursive=True) + BirdConfigPath = PathProperties(path=None, + perms=BirdConfigPerms, + create=True, + createRecursive=True, + setPerms=True, + checkPerms=True) + BirdConfigMount = MountProperties(target='/etc/bird', + source=BirdConfigPath) + mounts.append(BirdConfigMount) + mountConfigPairs['BirdConfigPath'] = BirdConfigMount + + return mounts, mountConfigPairs