Created
May 20, 2022 07:18
-
-
Save derde/400dc96daaaf3b7c7b180a9a69b7154f to your computer and use it in GitHub Desktop.
Give network interface to namespace, run shell, cleanup after exit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python3 | |
''' pppns - set ip netns for ppp0 ''' | |
import os | |
import pwd | |
import sys | |
import optparse | |
r={ | |
'ip': 'sudo ip', | |
'device': 'ppp0', | |
'namespace': 'nsppp0', | |
'username': pwd.getpwuid(os.getuid()).pw_name, | |
'getpid': os.getpid(), | |
} | |
def docmd(cmd): | |
sys.stderr.write('# '+cmd+'\n') | |
sys.stderr.flush() | |
return os.system(cmd) | |
def netns_setup(r): | |
inet=[] | |
docmd('sudo echo "device %(device)s netns %(namespace)s"' %r) | |
cmd='%(ip)s addr ls dev %(device)s' % r | |
fd=os.popen(cmd,'r') | |
for line in fd: | |
bits=line.strip().split() | |
if len(bits)<2: continue | |
if bits[0]=='inet' or bits[0]=='inet6': | |
inet.append(bits[1]) | |
routes=[] | |
for cmd in ( '%(ip)s route ls' % r , '%(ip)s -6 route ls' % r ): | |
fd=os.popen(cmd,'r') | |
for line in fd: | |
if line.find('dev %(device)s' % r)>=0: | |
i=line.find(' expires ') | |
if i>0: line=line[:i] | |
routes.append(line) | |
# Make namespace | |
docmd ( '%(ip)s netns add %(namespace)s' % r ) | |
# Add the link to the namespace | |
docmd( '%(ip)s link set %(device)s netns %(namespace)s' % r ) | |
# Bring it up | |
docmd( '%(ip)s netns exec %(namespace)s ip link set dev %(device)s up' % r ) | |
# Configure the link | |
for ipaddress in inet: | |
r['ipaddress']=ipaddress | |
docmd( '%(ip)s netns exec %(namespace)s ip addr add dev %(device)s %(ipaddress)s' % r ) | |
# Add the routes | |
for route in routes: | |
r['route']=route | |
docmd ( '%(ip)s netns exec %(namespace)s ip route add %(route)s' % r ) | |
docmd ( '%(ip)s netns exec %(namespace)s ip route add default dev %(device)s' % r ) | |
docmd ( '%(ip)s netns exec %(namespace)s ip -6 route add default dev %(device)s' % r ) | |
docmd ('%(ip)s netns exec %(namespace)s sudo -u %(username)s -s' % r) | |
# CLEANUP | |
docmd ( '%(ip)s netns exec %(namespace)s ip link set %(device)s netns %(getpid)s' % r ) | |
docmd( '%(ip)s link set dev %(device)s up' % r ) | |
for ipaddress in inet: | |
r['ipaddress']=ipaddress | |
docmd( '%(ip)s addr add dev %(device)s %(ipaddress)s' % r ) | |
for route in routes: | |
r['route']=route | |
docmd ( '%(ip)s route add %(route)s' % r ) | |
docmd( '%(ip)s netns del %(namespace)s' % r ) | |
docmd('echo Done') | |
if __name__=="__main__": | |
import optparse | |
usage="Usage: %prog [interface] [cmd]\n"+__doc__+"\n" | |
parser=optparse.OptionParser(usage) | |
parser.add_option("-d","--debug",dest="debug", action="count", default=0, help="DEBUG level") | |
parser.add_option("-n","--netns",dest="netns", action="store", default='', help="net namespace") | |
(options,args) = parser.parse_args() | |
cmd=[] | |
device='ppp0' | |
if len(args)>0: device=args[0] | |
if len(args)>1: cmd=args[1:] | |
r['device']=device | |
namespace=options.netns | |
if namespace=='': namespace='ns_'+device | |
r['namespace']=namespace | |
r['device']=device | |
netns_setup(r) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment