Prepare Open vSwitch 1.1.2 release.
[sliver-openvswitch.git] / debian / ovs-monitor-ipsec
index 00fcd3c..0a97c88 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/python
-# Copyright (c) 2009, 2010 Nicira Networks
+# Copyright (c) 2009, 2010, 2011 Nicira Networks
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -83,6 +83,7 @@ path certificate "%s";
     cert_entry = """remote %s {
         exchange_mode main;
         nat_traversal on;
+        ike_frag on;
         certificate_type x509 "%s" "%s";
         my_identifier asn1dn;
         peers_identifier asn1dn;
@@ -116,6 +117,9 @@ path certificate "%s";
         self.psk_hosts = {}
         self.cert_hosts = {}
 
+        if not os.path.isdir(self.cert_dir):
+            os.mkdir(self.cert_dir)
+
         # Clean out stale peer certs from previous runs
         for ovs_cert in glob.glob("%s/ovs-*.pem" % self.cert_dir):
             try:
@@ -202,9 +206,9 @@ path certificate "%s";
         if host in self.psk_hosts:
             raise error.Error("host %s already defined for psk" % host)
 
-        if "certificate" not in vals:
+        if vals["certificate"] == None:
             raise error.Error("'certificate' not defined for %s" % host)
-        elif "private_key" not in vals:
+        elif vals["private_key"] == None:
             # Assume the private key is stored in the same PEM file as 
             # the certificate.  We make a copy of "vals" so that we don't
             # modify the original "vals", which would cause the script
@@ -317,9 +321,9 @@ class IPsec:
         self.call_setkey("spdflush;")
 
     def spd_add(self, local_ip, remote_ip):
-        cmds = ("spdadd %s %s gre -P out ipsec esp/transport//default;\n" %
+        cmds = ("spdadd %s %s gre -P out ipsec esp/transport//require;\n" %
                     (local_ip, remote_ip))
-        cmds += ("spdadd %s %s gre -P in ipsec esp/transport//default;" %
+        cmds += ("spdadd %s %s gre -P in ipsec esp/transport//require;" %
                     (remote_ip, local_ip))
         self.call_setkey(cmds)
 
@@ -371,6 +375,8 @@ def keep_table_columns(schema, table_name, column_types):
  
 def monitor_uuid_schema_cb(schema):
     string_type = types.Type(types.BaseType(types.StringType))
+    optional_ssl_type = types.Type(types.BaseType(types.UuidType,
+                                                  ref_table='SSL'), None, 0, 1)
     string_map_type = types.Type(types.BaseType(types.StringType),
                                  types.BaseType(types.StringType),
                                  0, sys.maxint)
@@ -380,6 +386,11 @@ def monitor_uuid_schema_cb(schema):
         schema, "Interface", {"name": string_type,
                               "type": string_type,
                               "options": string_map_type})
+    new_tables["Open_vSwitch"] = keep_table_columns(
+        schema, "Open_vSwitch", {"ssl": optional_ssl_type})
+    new_tables["SSL"] = keep_table_columns(
+        schema, "SSL", {"certificate": string_type,
+                        "private_key": string_type})
     schema.tables = new_tables
 
 def usage():
@@ -410,6 +421,15 @@ def update_ipsec(ipsec, interfaces, new_interfaces):
         except error.Error, msg:
             s_log.warning("skipping ipsec config for %s: %s" % (name, msg))
 
+def get_ssl_cert(data):
+    for ovs_rec in data["Open_vSwitch"].itervalues():
+        if ovs_rec.ssl.as_list():
+            ssl_rec = data["SSL"][ovs_rec.ssl.as_scalar()]
+            return (ssl_rec.certificate.as_scalar(),
+                    ssl_rec.private_key.as_scalar())
+
+    return None
+
 def main(argv):
     try:
         options, args = getopt.gnu_getopt(
@@ -431,8 +451,6 @@ def main(argv):
                          "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
         sys.exit(1)
 
-    ovs.daemon.die_if_already_running()
     remote = args[0]
     idl = ovs.db.idl.Idl(remote, "Open_vSwitch", monitor_uuid_schema_cb)
 
@@ -447,30 +465,42 @@ def main(argv):
             idl.wait(poller)
             poller.block()
             continue
+
+        ssl_cert = get_ssl_cert(idl.data)
  
         new_interfaces = {}
         for rec in idl.data["Interface"].itervalues():
             if rec.type.as_scalar() == "ipsec_gre":
                 name = rec.name.as_scalar()
-                peer_cert = rec.options.get("peer_cert")
-                psk = rec.options.get("psk")
+                entry = {
+                    "remote_ip": rec.options.get("remote_ip"),
+                    "local_ip": rec.options.get("local_ip", "0.0.0.0/0"),
+                    "certificate": rec.options.get("certificate"),
+                    "private_key": rec.options.get("private_key"),
+                    "use_ssl_cert": rec.options.get("use_ssl_cert"),
+                    "peer_cert": rec.options.get("peer_cert"),
+                    "psk": rec.options.get("psk") }
 
-                if peer_cert and psk:
+                if entry["peer_cert"] and entry["psk"]:
                     s_log.warning("both 'peer_cert' and 'psk' defined for %s" 
                             % name)
                     continue
-                elif not peer_cert and not psk: 
+                elif not entry["peer_cert"] and not entry["psk"]:
                     s_log.warning("no 'peer_cert' or 'psk' defined for %s" 
                             % name)
                     continue
 
-                new_interfaces[name] = {
-                    "remote_ip": rec.options.get("remote_ip"),
-                    "local_ip": rec.options.get("local_ip", "0.0.0.0/0"),
-                    "certificate": rec.options.get("certificate"),
-                    "private_key": rec.options.get("private_key"),
-                    "peer_cert": peer_cert,
-                    "psk": psk }
+                # The "use_ssl_cert" option is deprecated and will
+                # likely go away in the near future.
+                if entry["use_ssl_cert"] == "true":
+                    if not ssl_cert:
+                        s_log.warning("no valid SSL entry for %s" % name)
+                        continue
+
+                    entry["certificate"] = ssl_cert[0]
+                    entry["private_key"] = ssl_cert[1]
+
+                new_interfaces[name] = entry
  
         if interfaces != new_interfaces:
             update_ipsec(ipsec, interfaces, new_interfaces)