setup-ipv6.py 3.29 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
#!/usr/bin/env python2

import os
import socket
from lxml import etree as ET

def findif(mac=None,ip=None):
    (output,thing) = (None,None)
    if mac:
        thing = mac.lower()
        if thing.find(":") == -1:
            thing = "%s:%s:%s:%s:%s:%s" % (
                mac[0:2],mac[2:4],mac[4:6],mac[6:8],mac[8:10],mac[10:])
        fd = os.popen("ip -br link")
        output = fd.read().splitlines()
        fd.close()
    elif ip:
        thing = ip
        fd = os.popen("ip -br addr")
        output = fd.read().splitlines()
        fd.close()
    else:
        return None
    for line in output:
        if thing in line:
            return line.split(' ')[0]
    return None

nsmap = {
    "g":"http://www.geni.net/resources/rspec/3",
    "c":"http://www.protogeni.net/resources/rspec/ext/johnsond/1"
}

hostname = socket.gethostname()
fd = os.popen("/usr/bin/geni-get manifest")
m = fd.read()
fd.close()

x = ET.fromstring(m)
node = None
for n in x.findall("g:node",namespaces=nsmap):
    host = n.find("g:host",namespaces=nsmap)
    if host is not None and host.get("name").lower() == hostname:
        node = n
        break
if not node:
    raise Exception(
        "unable to find manifest node matching hostname '%s'" % (hostname))

print "Setting addresses for %s ..." % (hostname,)

for i in node.findall("g:interface",namespaces=nsmap):
    mac = i.get("mac_address")
54 55 56
    dev = None
    if mac:
        dev = findif(mac=mac)
57 58 59 60
    addrs = []
    for a in i.findall("c:ip",namespaces=nsmap):
        if a.get("type") != "ipv6":
            continue
61 62 63
        (addr,prefixlen) = (a.get("address"),a.get("prefixlen"))
        addrs.append("%s/%s" % (addr,prefixlen))
    if dev and addrs:
64 65 66
        print "Enabling overall ipv6 forwarding and segment routing..."
        os.system("sysctl -w net.ipv6.conf.all.forwarding=1")
        os.system("sysctl -w net.ipv6.conf.all.seg6_enabled=1")
67 68 69 70 71
        print "Enabling segment routing for %s ..." % (dev,)
        os.system("sysctl -w net.ipv6.conf.%s.seg6_enabled=1" % (dev,))
        print "Enabling ipv6 forwarding for %s ..." % (dev,)
        os.system("sysctl -w net.ipv6.conf.%s.forwarding=1" % (dev,))
        print "Disabling ipv6 autoconf for %s ..." % (dev,)
72
        os.system("sysctl -w net.ipv6.conf.%s.autoconf=0" % (dev,))
73 74
        print "Flushing existing ipv6 addresses for %s ..." % (dev,)
        os.system("ip -6 addr flush dev %s" % (dev,))
75 76
        print "Downing interface %s to allow sysctls to take effect ..." % (dev,)
        os.system("ip link set %s down" % (dev,))
77 78 79
        for a in addrs:
            print "Adding address %s to %s" % (a,dev)
            os.system("ip -6 addr add %s dev %s" % (a,dev))
80 81
        print "Bringing up interface %s  ..." % (dev,)
        os.system("ip link set %s up" % (dev,))
82

83 84 85 86 87 88 89 90 91 92 93
# Collect ipv6 addrs for /etc/hosts
hostslines = []
for n in x.findall("g:node",namespaces=nsmap):
    for i in node.findall("g:interface",namespaces=nsmap):
        for a in i.findall("c:ip",namespaces=nsmap):
            if a.get("type") != "ipv6":
                continue
            (addr,prefixlen) = (a.get("address"),a.get("prefixlen"))
            name = i.get("client_id").replace(':','-')
            hostslines.append("%s\t%s\n" % (addr,name))

94 95 96 97 98
print "Writing to /etc/hosts..."
fd = open("/etc/hosts","a")
for line in hostslines:
    fd.write(line)
fd.close()