Skip to content

Instantly share code, notes, and snippets.

@derde
Created May 20, 2022 07:18
Show Gist options
  • Save derde/400dc96daaaf3b7c7b180a9a69b7154f to your computer and use it in GitHub Desktop.
Save derde/400dc96daaaf3b7c7b180a9a69b7154f to your computer and use it in GitHub Desktop.
Give network interface to namespace, run shell, cleanup after exit
#! /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