Commit 86cfd485 authored by Simon Redman's avatar Simon Redman

Add helper for enable IPv6 segment routing

parent b60a23af
......@@ -55,6 +55,14 @@ The most useful methods are:
- start_frr_on_network: Start frr on all nodes in the network
- stop_frr_on_network: Stop frr on all nodes in the network
#### 5.
This is an executable library which supports running sysctl commands
The only currently required command enables IPv6 segment routing
Everything can be automatically accomplished by the configure_nodes method
Once this codebase is finished, this section should go away. But great works are never finished, merely abandoned.
#!/usr/bin/env python3
# Copyright (C) 2018 Simon Redman <>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import ssh_helper
import argparse
import datetime
import getpass
import ipaddress
from netdiff import NetJsonParser
from typing import List
Build a valid sysctl command by using one SYSCTL_COMMAND_TEMPLATE then as many space-separated
SYSCTL_COMMAND_TEMPLATE = "sudo sysctl {lines}"
SYSCTL_SEG6_LINE_TEMPLATE = "net.ipv6.conf.{iface}.seg6_enabled=1"
def build_srg6_sysctl_command(interfaces: List[str]):
Construct the sysctl command to enable segment routing on all of the listed interfaces
:param interfaces: list of interface names
:return: sysctl configuration command
lines = []
for interface in interfaces:
return SYSCTL_COMMAND_TEMPLATE.format(lines=str.join(" ", lines))
def build_seg6_sysctl_commands_for_network(netgraph, ignore_nodes: List[str]=[]):
Build the command string to enable SRv6 for all nodes in the network
:param netgraph: networkx graph
:param ignore_nodes: List of nodes to not configure
:return: mapping of hosts to configurations
commands = []
for host in netgraph.nodes:
if host in ignore_nodes: continue
interfaces = netgraph._node[host]['interfaces'].keys()
return commands
def configure_nodes(netgraph, ignore_nodes: List[str]=[]):
Configure every node in the network to allow segment routing
:param netgraph: networkx graph object representing the network
:param ignore_nodes: List of nodes to not configure
:return: Output from the SSH commands
hosts = [host for host in netgraph.nodes if host not in ignore_nodes]
sessions = list(map(lambda host : netgraph._node[host]['session'], hosts))
seg6_sysctl_commands = build_seg6_sysctl_commands_for_network(netgraph, ignore_nodes)
# Push configurations commands to all nodes
return ssh_helper.run_commands_on_many_hosts(sessions, seg6_sysctl_commands)
if __name__ == "__main__":
parser = argparse.ArgumentParser("Configure Free Range Routing's OSPFv6 and Zebra for all nodes in the network")
parser.add_argument("--in-file", action='store', type=str, required=True,
help="Path to the NetJSON file to parse")
parser.add_argument("--username", action='store', type=str, default=getpass.getuser(),
help="Username to use on all hosts. Defaults to current user's username")
parser.add_argument("--stop", action='store', type=bool, default=False,
help="Stop all services (after writing config files)")
args = parser.parse_args()
netgraph = NetJsonParser(file=args.in_file)
ssh_helper.network_graph_login(netgraph.graph, args.username)
outputs = configure_nodes(netgraph.graph)
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment