ovs-monitor-ipsec: Add unixctl support.
[sliver-openvswitch.git] / debian / ovs-monitor-ipsec
index f7bdf1d..e89e709 100755 (executable)
@@ -37,11 +37,19 @@ from ovs.db import types
 import ovs.util
 import ovs.daemon
 import ovs.db.idl
+import ovs.unixctl
 import ovs.vlog
 
 vlog = ovs.vlog.Vlog("ovs-monitor-ipsec")
 root_prefix = ''                # Prefix for absolute file names, for testing.
 setkey = "/usr/sbin/setkey"
+exiting = False
+
+
+def unixctl_exit(conn, unused_argv, unused_aux):
+    global exiting
+    exiting = True
+    conn.reply(None)
 
 
 # Class to configure the racoon daemon, which handles IKE negotiation
@@ -216,13 +224,10 @@ path certificate "%s";
 
         # The peer's certificate comes to us in PEM format as a string.
         # Write that string to a file for Racoon to use.
-        peer_cert_file = "%s/ovs-%s.pem" % (self.cert_dir, host)
-        f = open(root_prefix + peer_cert_file, "w")
+        f = open(root_prefix + vals["peer_cert_file"], "w")
         f.write(vals["peer_cert"])
         f.close()
 
-        vals["peer_cert_file"] = peer_cert_file
-
         self.cert_hosts[host] = vals
         self.commit()
 
@@ -399,11 +404,13 @@ def update_ipsec(ipsec, interfaces, new_interfaces):
         orig_vals = interfaces.get(name)
         if orig_vals:
             # Configuration for this host already exists.  Check if it's
-            # changed.
-            if vals == orig_vals:
-                continue
-            else:
+            # changed.  We use set difference, since we want to ignore
+            # any local additions to "orig_vals" that we've made
+            # (e.g. the "peer_cert_file" key).
+            if set(vals.items()) - set(orig_vals.items()):
                 ipsec.del_entry(vals["local_ip"], vals["remote_ip"])
+            else:
+                continue
 
         try:
             ipsec.add_entry(vals["local_ip"], vals["remote_ip"], vals)
@@ -413,9 +420,10 @@ def update_ipsec(ipsec, interfaces, new_interfaces):
 
 def get_ssl_cert(data):
     for ovs_rec in data["Open_vSwitch"].rows.itervalues():
-        ssl = ovs_rec.ssl
-        if ssl and ssl.certificate and ssl.private_key:
-            return (ssl.certificate, ssl.private_key)
+        if ovs_rec.ssl:
+            ssl = ovs_rec.ssl[0]
+            if ssl.certificate and ssl.private_key:
+                return (ssl.certificate, ssl.private_key)
 
     return None
 
@@ -447,12 +455,22 @@ def main():
 
     ovs.daemon.daemonize()
 
+    ovs.unixctl.command_register("exit", "", 0, 0, unixctl_exit, None)
+    error, unixctl_server = ovs.unixctl.UnixctlServer.create(None)
+    if error:
+        ovs.util.ovs_fatal(error, "could not create unixctl server", vlog)
+
     ipsec = IPsec()
 
     interfaces = {}
     while True:
+        unixctl_server.run()
+        if exiting:
+            break
+
         if not idl.run():
             poller = ovs.poller.Poller()
+            unixctl_server.wait(poller)
             idl.wait(poller)
             poller.block()
             continue
@@ -464,6 +482,7 @@ def main():
             if rec.type == "ipsec_gre":
                 name = rec.name
                 options = rec.options
+                peer_cert_name = "ovs-%s.pem" % (options.get("remote_ip"))
                 entry = {
                     "remote_ip": options.get("remote_ip"),
                     "local_ip": options.get("local_ip", "0.0.0.0/0"),
@@ -471,6 +490,7 @@ def main():
                     "private_key": options.get("private_key"),
                     "use_ssl_cert": options.get("use_ssl_cert"),
                     "peer_cert": options.get("peer_cert"),
+                    "peer_cert_file": Racoon.cert_dir + "/" + peer_cert_name,
                     "psk": options.get("psk")}
 
                 if entry["peer_cert"] and entry["psk"]:
@@ -497,6 +517,9 @@ def main():
             update_ipsec(ipsec, interfaces, new_interfaces)
             interfaces = new_interfaces
 
+    unixctl_server.close()
+    idl.close()
+
 
 if __name__ == '__main__':
     try: