mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 12:28:42 +00:00
122 lines
4.9 KiB
Python
Executable File
122 lines
4.9 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
#!/usr/bin/env python3
|
|
# Copyright (c) 2015-2016 Savoir-faire Linux Inc.
|
|
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import argparse, subprocess
|
|
|
|
from pyroute2 import IPDB, NetNS
|
|
from pyroute2.netns.process.proxy import NSPopen
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description='Creates a virtual network topology for testing')
|
|
parser.add_argument('-i', '--ifname', help='interface name', default='ethdht')
|
|
parser.add_argument('-n', '--ifnum', type=int, help='number of isolated interfaces to create', default=1)
|
|
parser.add_argument('-r', '--remove', help='remove instead of adding network interfaces', action="store_true")
|
|
parser.add_argument('-l', '--loss', help='simulated packet loss (percent)', type=int, default=0)
|
|
parser.add_argument('-d', '--delay', help='simulated latency (ms)', type=int, default=0)
|
|
parser.add_argument('-4', '--ipv4', help='Enable IPv4', action="store_true")
|
|
parser.add_argument('-6', '--ipv6', help='Enable IPv6', action="store_true")
|
|
|
|
args = parser.parse_args()
|
|
|
|
local_addr4 = '10.0.42.'
|
|
local_addr6 = '2001:db9::'
|
|
brige_name = 'br'+args.ifname
|
|
|
|
ip = None
|
|
try:
|
|
ip = IPDB()
|
|
if args.remove:
|
|
# cleanup interfaces
|
|
for ifn in range(args.ifnum):
|
|
iface = args.ifname+str(ifn)
|
|
if iface in ip.interfaces:
|
|
with ip.interfaces[iface] as i:
|
|
i.remove()
|
|
if 'tap'+args.ifname in ip.interfaces:
|
|
with ip.interfaces['tap'+args.ifname] as i:
|
|
i.remove()
|
|
if brige_name in ip.interfaces:
|
|
with ip.interfaces[brige_name] as i:
|
|
i.remove()
|
|
for ifn in range(args.ifnum):
|
|
netns = NetNS('node'+str(ifn))
|
|
netns.close()
|
|
netns.remove()
|
|
else:
|
|
for ifn in range(args.ifnum):
|
|
iface = args.ifname+str(ifn)
|
|
if not iface in ip.interfaces:
|
|
ip.create(kind='veth', ifname=iface, peer=iface+'.1').commit()
|
|
|
|
ip.create(kind='tuntap', ifname='tap'+args.ifname, mode='tap').commit()
|
|
|
|
with ip.create(kind='bridge', ifname=brige_name) as i:
|
|
for ifn in range(args.ifnum):
|
|
iface = args.ifname+str(ifn)
|
|
i.add_port(ip.interfaces[iface])
|
|
i.add_port(ip.interfaces['tap'+args.ifname])
|
|
if args.ipv4:
|
|
i.add_ip(local_addr4+'1/24')
|
|
if args.ipv6:
|
|
i.add_ip(local_addr6+'1/64')
|
|
i.up()
|
|
|
|
with ip.interfaces['tap'+args.ifname] as tap:
|
|
tap.up()
|
|
|
|
for ifn in range(args.ifnum):
|
|
iface = args.ifname+str(ifn)
|
|
|
|
nns = NetNS('node'+str(ifn))
|
|
iface1 = iface+'.1'
|
|
with ip.interfaces[iface1] as i:
|
|
i.net_ns_fd = nns.netns
|
|
|
|
with ip.interfaces[iface] as i:
|
|
i.up()
|
|
|
|
ip_ns = IPDB(nl=nns)
|
|
try:
|
|
with ip_ns.interfaces.lo as lo:
|
|
lo.up()
|
|
with ip_ns.interfaces[iface1] as i:
|
|
if args.ipv4:
|
|
i.add_ip(local_addr4+str(ifn+8)+'/24')
|
|
if args.ipv6:
|
|
i.add_ip(local_addr6+str(ifn+8)+'/64')
|
|
i.up()
|
|
finally:
|
|
ip_ns.release()
|
|
|
|
nsp = NSPopen(nns.netns, ["tc", "qdisc", "add", "dev", iface1, "root", "netem", "delay", str(args.delay)+"ms", str(int(args.delay/2))+"ms", "loss", str(args.loss)+"%", "25%"], stdout=subprocess.PIPE)
|
|
#print(nsp.communicate()[0].decode())
|
|
nsp.communicate()
|
|
nsp.wait()
|
|
nsp.release()
|
|
|
|
if args.ipv4:
|
|
subprocess.call(["sysctl", "-w", "net.ipv4.conf."+brige_name+".forwarding=1"])
|
|
if args.ipv6:
|
|
subprocess.call(["sysctl", "-w", "net.ipv6.conf."+brige_name+".forwarding=1"])
|
|
|
|
except Exception as e:
|
|
print('Error',e)
|
|
finally:
|
|
if ip:
|
|
ip.release()
|