Commit b448b200 authored by Sigmund Augdal's avatar Sigmund Augdal

Rewrite neigbor code to use etcd as backend

parent b03e0d54
......@@ -11,6 +11,7 @@ log = logging.getLogger("neighbors")
#
from pyroute2.netlink.iproute import IPRoute
import sys
import etcd
def byteswap(a):
......@@ -22,13 +23,19 @@ def ifindex(interface):
return int(open("/sys/class/net/{}/ifindex".format(interface)).read().rstrip())
V4 = 0
V6_LL = 1
V6_PUB = 2
V4 = "ipv4"
V6_LL = "ipv6_ll"
V6_PUB = "ipv6_public"
def etcd_key(mac, addrtype):
return "nova/iaas/instances/{}/{}".format(mac, addrtype)
class NeighborCache(object):
def __init__(self, interface, routers):
def __init__(self, ssl_cert, ssl_key, cacert, interface, routers):
self.etcd_client = etcd.Etcd(ssl_key=ssl_key, ssl_cert=ssl_cert,
verify=cacert)
self.caches = ({}, {}, {})
self.ifindex = ifindex(interface)
self.ir = IPRoute()
......@@ -44,25 +51,32 @@ class NeighborCache(object):
for np in neighbors:
self.process_event(np)
def get_cache(self, addrtype):
macaddresses = self.caches[addrtype]
return macaddresses
def get_ipaddress_from_mac(self, mac, addrtype):
return self.get_cache(addrtype).get(mac, None)
try:
return self.etcd_client.get(etcd_key(mac, addrtype)).value
except etcd.EtcdError as ex:
if ex.args[0] == 100:
return None
raise ex
def get_mac_from_ipaddress(self, ipaddress, addrtype):
macaddresses = self.get_cache(addrtype)
macs = [k for k in macaddresses if macaddresses[k] == ipaddress]
if len(macs) == 0:
return None
if len(macs) > 1:
raise RuntimeError("Duplicate ip address in cache")
return macs[0]
try:
for entry in self.etcd_client.list("nova/iaas/instances"):
if entry.dir:
mac = entry.key.split("/")[-1]
try:
if self.etcd_client.get(entry.key + "/" + addrtype).value == ipaddress:
return mac
except etcd.EtcdError as ex:
if ex.args[0] != 100:
raise ex
except etcd.EtcdError as ex:
if ex.args[0] == 100:
return None
return None
def add_pair(self, mac, ipaddress, addrtype):
macaddresses = self.get_cache(addrtype)
macaddresses[mac] = ipaddress
self.etcd_client.testandset(etcd_key(mac, addrtype), "", ipaddress)
def new(self, mac, ipaddr, addrtype):
old_address = self.get_ipaddress_from_mac(mac, addrtype)
......@@ -86,10 +100,7 @@ class NeighborCache(object):
self.add_pair(mac, ipaddr, addrtype)
def remove(self, mac, ipaddress, addrtype):
log.debug("Removing reference to %s: %s", mac, ipaddress)
macs = self.get_cache(addrtype)
if mac in macs:
del(macs[mac])
self.etcd_client.delete(etcd_key(mac, addrtype))
def process_event(self, np):
if np['event'] == 'RTM_NEWNEIGH':
......@@ -122,7 +133,12 @@ class NeighborCache(object):
def main():
logging.basicConfig(level=logging.DEBUG)
cache = NeighborCache(sys.argv[1], sys.argv[2:])
logging.getLogger("requests").setLevel(logging.INFO)
ssl_cert = "/etc/etcd/server.crt"
ssl_key = "/etc/etcd/server.key"
cacert = "/etc/etcd/myca.crt"
cache = NeighborCache(ssl_cert, ssl_key, cacert, sys.argv[1], sys.argv[2:])
cache.run()
if __name__ == '__main__':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment