Support controller discovery in Debian packages.
authorBen Pfaff <blp@nicira.com>
Wed, 23 Jul 2008 20:11:00 +0000 (13:11 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 23 Jul 2008 20:12:23 +0000 (13:12 -0700)
debian/ofp-switch-setup
debian/openflow-controller.README.Debian
debian/openflow-switch.default
debian/openflow-switch.init
debian/openflow-switch.install
debian/openflow-switch.manpages
debian/openflow-switch.templates
debian/po/templates.pot
include/dhcp.h
secchan/secchan.8.in

index 0c03c3323015b927f528ad0a94a44ef985363e0c..74f3f87d511fc800e2163b7a7f6ab366e1118d4c 100755 (executable)
@@ -12,15 +12,20 @@ my $debconf_owner = 'openflow-switch';
 
 my $default = '/etc/default/openflow-switch';
 my $etc = '/etc/openflow-switch';
+my $rundir = '/var/run';
 my $privkey_file = "$etc/of0-privkey.pem";
 my $req_file = "$etc/of0-req.pem";
 my $cert_file = "$etc/of0-cert.pem";
 my $cacert_file = "$etc/cacert.pem";
+my $ofp_discover_pidfile = "$rundir/ofp-discover.pid";
 
 my $ua = LWP::UserAgent->new;
 $ua->timeout(10);
 $ua->env_proxy;
 
+system("/etc/init.d/openflow-switch stop 1>&2");
+kill_ofp_discover();
+
 version('2.0');
 capb('backup');
 title('OpenFlow Switch Setup');
@@ -38,8 +43,9 @@ if (-e $default) {
            db_set('netdevs', join(', ', map($netdevs{$_},
                                             grep(exists $netdevs{$_}, split))))
        },
-       IN_BAND => sub {
-           db_set('band', $_ eq 'no' ? 'in-band' : 'out-of-band')
+       MODE => sub {
+           db_set('mode',
+                  $_ eq 'in-band' || $_ eq 'out-of-band' ? $_ : 'discovery')
        },
        SWITCH_IP => sub { db_set('switch-ip', $_) },
        CONTROLLER => sub { db_set('controller-vconn', $_) },
@@ -71,6 +77,8 @@ if (! -e $cert_file) {
     $req_fingerprint = sha1_hex($req);
 }
 
+my %options;
+
 my (@states) =
   (sub {
        # User backed up from first dialog box.
@@ -101,12 +109,69 @@ my (@states) =
        }
    },
    sub {
-       # In-band or out-of-band controller?
-       db_input('band');
+       # Discovery or in-band or out-of-band controller?
+       db_input('mode');
        return;
    },
    sub {
-       return 'skip' if db_get('band') eq 'out-of-band';
+       return 'skip' if db_get('mode') ne 'discovery';
+       for (;;) {
+           # Notify user that we are going to do discovery.
+           db_input('discover');
+           return 'prev' if db_go();
+           print STDERR "Please wait up to 30 seconds for discovery...\n";
+
+           # Make sure that there's no running discovery process.
+           kill_ofp_discover();
+
+           # Do discovery.
+           %options = ();
+           open(DISCOVER, '-|', 'ofp-discover --timeout=30 --pidfile '
+                . join(' ', netdev_names()));
+           while (<DISCOVER>) {
+               chomp;
+               if (my ($name, $value) = /^([^=]+)=(.*)$/) {
+                   if ($value =~ /^"(.*)"$/) {
+                       $value = $1;
+                       $value =~ s/\\([0-7][0-7][0-7])/chr($1)/ge;
+                   } else {
+                       $value =~ s/^(0x[[:xdigit:]]+)$/hex($1)/e;
+                   }
+                   $options{$name} = $value;
+               }
+               last if /^$/;
+           }
+
+           # Check results.
+           my $vconn = $options{'ofp-controller-vconn'};
+           my $pki_uri = $options{'ofp-pki-uri'};
+           return 'next'
+             if (defined($vconn)
+                 && is_valid_vconn($vconn)
+                 && (!is_ssl_vconn($vconn) || defined($pki_uri)));
+
+           # Try again?
+           kill_ofp_discover();
+           db_input('discovery-failure');
+           db_go();
+       }
+   },
+   sub {
+       return 'skip' if db_get('mode') ne 'discovery';
+
+       my $vconn = $options{'ofp-controller-vconn'};
+       my $pki_uri = $options{'ofp-pki-uri'};
+       db_subst('discovery-success', 'controller-vconn', $vconn);
+       db_subst('discovery-success',
+                'pki-uri', is_ssl_vconn($vconn) ? $pki_uri : "no PKI in use");
+       db_input('discovery-success');
+       return 'prev' if db_go();
+       db_set('controller-vconn', $vconn);
+       db_set('pki-uri', $pki_uri);
+       return 'next';
+   },
+   sub {
+       return 'skip' if db_get('mode') ne 'in-band';
        for (;;) {
            db_input('switch-ip');
            return 'prev' if db_go();
@@ -119,16 +184,16 @@ my (@states) =
        }
    },
    sub {
+       return 'skip' if db_get('mode') eq 'discovery';
        for (;;) {
            my $old_vconn = db_get('controller-vconn');
            db_input('controller-vconn');
            return 'prev' if db_go();
 
            my $vconn = db_get('controller-vconn');
-           if ($vconn =~ /^(tcp|ssl):([^:]+)(:.*)?/) {
-               if ($old_vconn ne $vconn
-                   || db_get('pki-host') eq '') {
-                   db_set('pki-host', $2);
+           if (is_valid_vconn($vconn)) {
+               if ($old_vconn ne $vconn || db_get('pki-uri') eq '') {
+                   db_set('pki-uri', pki_host_to_uri($2));
                }
                return 'next';
            }
@@ -141,7 +206,7 @@ my (@states) =
        return 'skip' if !ssl_enabled();
        return 'skip' if -e $cacert_file && -e $cert_file;
 
-       db_input('pki-host');
+       db_input('pki-uri');
        return 'prev' if db_go();
        return;
    },
@@ -149,8 +214,16 @@ my (@states) =
        return 'skip' if !ssl_enabled();
        return 'skip' if -e $cacert_file;
 
-       my $pki_host = db_get('pki-host');
-       my $url = "http://$pki_host/openflow/pki/controllerca/cacert.pem";
+       my $pki_uri = db_get('pki-uri');
+       if ($pki_uri !~ /:/) {
+           $pki_uri = pki_host_to_uri($pki_uri);
+       } else {
+           # Trim trailing slashes.
+           $pki_uri =~ s%/+$%%;
+       }
+       db_set('pki-uri', $pki_uri);
+
+       my $url = "$pki_uri/controllerca/cacert.pem";
        my $response = $ua->get($url, ':content_file' => $cacert_file);
        if ($response->is_success) {
            return 'next';
@@ -158,7 +231,7 @@ my (@states) =
 
        db_subst('fetch-cacert-failed', 'url', $url);
        db_subst('fetch-cacert-failed', 'error', $response->status_line);
-       db_subst('fetch-cacert-failed', 'pki-host', $pki_host);
+       db_subst('fetch-cacert-failed', 'pki-uri', $pki_uri);
        db_input('fetch-cacert-failed');
        db_go();
        return 'prev';
@@ -173,8 +246,9 @@ my (@states) =
            return 'prev' if db_go();
            return 'next' if db_get('send-cert-req') eq 'no';
 
-           my $pki_host = db_get('pki-host');
-           my $url = "http://$pki_host/cgi-bin/ofp-pki-cgi";
+           my $pki_uri = db_get('pki-uri');
+           my ($pki_base_uri) = $pki_uri =~ m%^([^/]+://[^/]+)/%;
+           my $url = "$pki_base_uri/cgi-bin/ofp-pki-cgi";
            my $response = $ua->post($url, {'type' => 'switch',
                                            'req' => $req});
            return 'next' if $response->is_success;
@@ -182,8 +256,7 @@ my (@states) =
            db_subst('send-cert-req-failed', 'url', $url);
            db_subst('send-cert-req-failed', 'error',
                     $response->status_line);
-           db_subst('send-cert-req-failed', 'pki-host',
-                    $pki_host);
+           db_subst('send-cert-req-failed', 'pki-uri', $pki_uri);
            db_input('send-cert-req-failed');
            db_go();
        }
@@ -210,8 +283,8 @@ my (@states) =
            return 'prev' if db_go();
            exit(1) if db_get('fetch-switch-cert') eq 'no';
 
-           my $pki_host = db_get('pki-host');
-           my $url = "http://$pki_host/openflow/pki/switchca/certs/$req_fingerprint-cert.pem";
+           my $pki_uri = db_get('pki-uri');
+           my $url = "$pki_uri/switchca/certs/$req_fingerprint-cert.pem";
            my $response = $ua->get($url, ':content_file' => $cert_file);
            if ($response->is_success) {
                return 'next';
@@ -220,8 +293,7 @@ my (@states) =
            db_subst('fetch-switch-cert-failed', 'url', $url);
            db_subst('fetch-switch-cert-failed', 'error',
                     $response->status_line);
-           db_subst('fetch-switch-cert-failed', 'pki-host',
-                    $pki_host);
+           db_subst('fetch-switch-cert-failed', 'pki-uri', $pki_uri);
            db_input('fetch-switch-cert-failed');
            db_go();
        }
@@ -256,24 +328,25 @@ for (;;) {
 }
 
 my %config;
-$config{NETDEVS} = join(' ', map(/^(\S+)/, split(', ', db_get('netdevs'))));
-if (db_get('band') eq 'in-band') {
-    $config{IN_BAND} = 'yes';
+$config{NETDEVS} = join(' ', netdev_names());
+$config{MODE} = db_get('mode');
+if (db_get('mode') eq 'in-band') {
     $config{SWITCH_IP} = db_get('switch-ip');
-} else {
-    $config{IN_BAND} = 'no';
 }
-$config{CONTROLLER} = db_get('controller-vconn');
+if (db_get('mode') ne 'discovery') {
+    $config{CONTROLLER} = db_get('controller-vconn');
+}
 $config{PRIVKEY} = $privkey_file;
 $config{CERT} = $cert_file;
 $config{CACERT} = $cacert_file;
 save_config($default, %config);
 
 dup2(2, 1);                     # Get stdout back.
-system("/etc/init.d/openflow-switch restart");
+kill_ofp_discover();
+system("/etc/init.d/openflow-switch start");
 
 sub ssl_enabled {
-    return db_get('controller-vconn') =~ /^ssl:/;
+    return is_ssl_vconn(db_get('controller-vconn'));
 }
 
 sub db_subst {
@@ -288,7 +361,7 @@ sub db_subst {
 
 sub db_set {
     my ($question, $value) = @_;
-    $question = "$debconf_owner/$question";
+   $question = "$debconf_owner/$question";
     my ($ret, $seen) = set($question, $value);
     if ($ret && $ret != 30) {
         die "Error setting debconf question $question to $value: $seen";
@@ -415,7 +488,9 @@ sub load_config {
 
 sub shell_escape {
     local $_ = $_[0];
-    if (m&^[-a-zA-Z0-9:./%^_+,]*$&) {
+    if ($_ eq '') {
+        return '""';
+    } elsif (m&^[-a-zA-Z0-9:./%^_+,]*$&) {
         return $_;
     } else {
         s/'/'\\''/;
@@ -485,3 +560,28 @@ sub save_config {
     close(NEWFILE);
     rename("$file.tmp", $file) or die "$file.tmp: rename to $file: $!\n";
 }
+
+sub pki_host_to_uri {
+    my ($pki_host) = @_;
+    return "http://$pki_host/openflow/pki";
+}
+
+sub kill_ofp_discover {
+    # Delegate this to a subprocess because there is no portable way
+    # to invoke fcntl(F_GETLK) from Perl.
+    system("ofp-kill --force $ofp_discover_pidfile");
+}
+
+sub netdev_names {
+    return map(/^(\S+)/, split(', ', db_get('netdevs')));
+}
+
+sub is_valid_vconn {
+    my ($vconn) = @_;
+    return scalar($vconn =~ /^(tcp|ssl):([^:]+)(:.*)?/);
+}
+
+sub is_ssl_vconn {
+    my ($vconn) = @_;
+    return scalar($vconn =~ /^ssl:/);
+}
index c54e56999edac140e9949ddc525c9157ddda5723..19d5cb9b864e84972d568e82dedbe270eb1cc66b 100644 (file)
@@ -1,5 +1,10 @@
 README.Debian for openflow-controller
 -------------------------------------
 
-* To reconfigure the controller, edit /etc/default/openflow-controller
+* To (re)configure the controller, edit /etc/default/openflow-controller
   and run "/etc/init.d/openflow-controller restart".
+
+* To enable OpenFlow switches to automatically discover the location
+  of the controller, you must install and configure a DHCP server.
+  The secchan(8) manpage (found in the openflow-switch package) gives
+  a working example configuration file for the ISC DHCP server.
index f2ce5a6ae8a40b12d49c252f15c232d5ba1ec6eb..e4fb07bc65e76b8b7cefab09528b14ed907f278b 100644 (file)
 # become part of the switch and cannot be used for other purposes.
 #NETDEVS=""
 
-# IN_BAND: The OpenFlow switch must be able to contact the OpenFlow
-# controller over the network.  It can do so in one of two ways:
+# MODE: The OpenFlow switch has three modes that determine how it
+# reaches the controller:
+#
+# * in-band with discovery: A single network is used for OpenFlow
+#   traffic and other data traffic; that is, the switch contacts the
+#   controller over one of the network devices selected as OpenFlow
+#   switch ports.  The switch automatically determines the location of
+#   the controller using a DHCP request with an OpenFlow-specific
+#   vendor option.  This is the most common case.
 # 
-# * in-band: A single network is used for OpenFlow traffic and other
-#   data traffic; that is, the switch contacts the controller over one
-#   of the network devices selected as OpenFlow switch ports in the
-#   previous question.  This is the most common case.
+# * in-band: As above, but the location of the controller is manually
+#   configured.
 # 
 # * out-of-band: OpenFlow traffic uses a network separate from the
 #   data traffic that it controls.  If this is the case, the control
 #   one of those selected as an OpenFlow switch port in the previous
 #   question.
 #
-# Set IN_BAND to yes for in-band control, or to no for out-of-band
-# control.
-IN_BAND=yes
+# Set MODE to 'discovery', 'in-band', or 'out-of-band' for these
+# respective cases.
+MODE=discovery
 
-# SWITCH_IP: For in-band communication with the controller, the
-# OpenFlow switch must be able to determine its own IP address.  Its
-# IP address may be configured statically or dynamically:
+# SWITCH_IP: In 'in-band' mode, the switch's IP address may be
+# configured statically or dynamically:
 # 
 # * For static configuration, specify the switch's IP address as a
 #   string.
@@ -51,7 +55,7 @@ IN_BAND=yes
 #   if the network topology allows the switch to contact the DHCP
 #   server before it connects to the OpenFlow controller.
 #
-# If IN_BAND is set to "no" above, this setting has no effect.
+# This setting has no effect unless MODE is set to 'in-band'.
 SWITCH_IP=dhcp
 
 # CONTROLLER: Location of controller.
@@ -59,6 +63,7 @@ SWITCH_IP=dhcp
 #  tcp:HOST[:PORT]         via TCP to PORT (default: 975) on HOST
 #  ssl:HOST[:PORT]         via SSL to PORT (default: 976) on HOST
 # The default below assumes that the controller is running locally.
+# This setting has no effect when MODE is set to 'discovery'.
 #CONTROLLER="tcp:127.0.0.1"
 
 # PRIVKEY: Name of file containing switch's private key.
index 1f03df104f4b3f5ba715f1279ce4c509e41d54ed..74412d9095a4becfbc71efc77eaa4188675410a5 100755 (executable)
@@ -108,6 +108,23 @@ check_op() {
     fi
 }
 
+configure_ssl() {
+    if test ! -e "$PRIVKEY" || test ! -e "$CERT" || test ! -e "$CACERT"; then
+        if test ! -e "$PRIVKEY"; then
+            echo "$PRIVKEY: private key missing" >&2
+        fi
+        if test ! -e "$CERT"; then
+            echo "$CERT: certificate for private key missing" >&2
+        fi
+        if test ! -e "$CACERT"; then
+            echo "$CACERT: CA certificate missing" >&2
+        fi
+        echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
+        exit 1
+    fi
+    SSL_OPTS="--private-key=$PRIVKEY --certificate=$CERT --ca-cert=$CACERT"
+}
+
 case "$1" in
     start)
         if test -z "$NETDEVS"; then
@@ -115,40 +132,36 @@ case "$1" in
             echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
             exit 0
         fi
-        if test -z "$CONTROLLER"; then
-            echo "$default: No controller configured, switch disabled" >&2
-            echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
-            exit 0
-        fi
-        if test "$IN_BAND" != yes && test "$IN_BAND" != no; then
-            echo "$default: IN_BAND must set to 'yes' or 'no'" >&2
+        if test "$MODE" = discovery; then
+            unset CONTROLLER
+        elif test "$MODE" = in-band || test "$MODE" = out-of-band; then
+            if test -z "$CONTROLLER"; then
+                echo "$default: No controller configured and not configured for discovery, switch disabled" >&2
+                echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
+                exit 0
+            fi
+        else
+            echo "$default: MODE must set to 'discovery', 'in-band', or 'out-of-band'" >&2
             echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
             exit 1
         fi
+        : ${PRIVKEY:=/etc/openflow-switch/of0-privkey.pem}
+        : ${CERT:=/etc/openflow-switch/of0-cert.pem}
+        : ${CACERT:=/etc/openflow-switch/cacert.pem}
         case $CONTROLLER in
+            '')
+                # Discovery mode.
+                if test -e "$PRIVKEY"; then
+                    configure_ssl
+                fi
+                ;;
             tcp:*)
                 ;;
             ssl:*)
-                : ${PRIVKEY:=/etc/openflow-switch/of0-privkey.pem}
-                : ${CERT:=/etc/openflow-switch/of0-cert.pem}
-                : ${CACERT:=/etc/openflow-switch/cacert.pem}
-                if test ! -e "$PRIVKEY" || test ! -e "$CERT" ||
-                    test ! -e "$CACERT"; then
-                    if test ! -e "$PRIVKEY"; then
-                        echo "$PRIVKEY: private key missing" >&2
-                    fi
-                    if test ! -e "$CERT"; then
-                        echo "$CERT: certificate for private key missing" >&2
-                    fi
-                    if test ! -e "$CACERT"; then
-                        echo "$CACERT: CA certificate missing" >&2
-                    fi
-                    echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
-                    exit 1
-                fi
+                configure_ssl
                 ;;
             *)
-                echo "$default: CONTROLLER must be in the form 'ssl:HOST[:PORT]' or 'tcp:HOST[:PORT]'" >&2
+                echo "$default: CONTROLLER must be in the form 'ssl:HOST[:PORT]' or 'tcp:HOST[:PORT]' when not in discovery mode" >&2
                 echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
                 exit 1
         esac
@@ -174,7 +187,7 @@ case "$1" in
             must_succeed "Adding $netdev to datapath" dpctl addif nl:0 $netdev
         done
 
-        if test "$IN_BAND" = yes; then
+        if test "$MODE" = in-band; then
             if test "$SWITCH_IP" = dhcp; then
                 must_succeed "Temporarily disabling of0" ifconfig of0 down
             else
@@ -194,7 +207,7 @@ case "$1" in
             echo " ERROR."
         fi
 
-        if test "$IN_BAND" = yes && test "$SWITCH_IP" = dhcp; then
+        if test "$MODE" = in-band && test "$SWITCH_IP" = dhcp; then
             echo -n "Starting dhclient on of0: "
            start-stop-daemon --start --quiet --pidfile $DHCLIENT_PIDFILE \
                --exec /sbin/dhclient -- -q -pf $DHCLIENT_PIDFILE of0
index 77ea13af00ea6f6e979cc1db5e87df30e5ec0fba..2c85136180e5871ed1dc4271c29f79942331f2dc 100644 (file)
@@ -1,4 +1,6 @@
 _debian/switch/switch usr/sbin
 _debian/secchan/secchan usr/sbin
 _debian/utilities/dpctl usr/sbin
+_debian/utilities/ofp-discover usr/sbin
+_debian/utilities/ofp-kill usr/sbin
 debian/ofp-switch-setup usr/sbin
index 9f4c4ff89f22920ad4d7e882935b81db6a74f07e..b012d8dbfbb28427b0adaab7c8e2ffef81628892 100644 (file)
@@ -1,4 +1,6 @@
 debian/ofp-switch-setup.8
 _debian/secchan/secchan.8
 _debian/switch/switch.8
+_debian/utilities/ofp-discover.8
+_debian/utilities/ofp-kill.8
 utilities/dpctl.8
index c6d4b5e4cb0030b27bf960c308acd49626570caa..7876109798ec02b9f3081500ed3105f0e8947dda 100644 (file)
@@ -35,24 +35,59 @@ _Description: Some Network Devices Have IP or IPv6 Addresses
  If this is an unintentional mistake, move back and fix the selection,
  or de-configure the IP or IPv6 from these network devices.
 
-Template: openflow-switch/band
+Template: openflow-switch/mode
 Type: select
-_Choices: in-band, out-of-band
-Default: in-band
+_Choices: discovery, in-band, out-of-band
+Default: discovery
 _Description: Switch-to-controller access method:
  The OpenFlow switch must be able to contact the OpenFlow controller over
- the network.  It can do so in one of two ways:
+ the network.  It can do so in one of three ways:
  .
- in-band: A single network is used for OpenFlow traffic and other data
- traffic; that is, the switch contacts the controller over one of the
- network devices selected as OpenFlow switch netdevs in the previous
- question.  This is the most common case.
+ discovery: A single network is used for OpenFlow traffic and other
+ data traffic; that is, the switch contacts the controller over one of
+ the network devices selected as OpenFlow switch network devices in
+ the previous question.  The switch automatically determines the
+ location of the controller using a DHCP request with an
+ OpenFlow-specific vendor option.  This is the most common case.
+ .
+ in-band: As above, but the location of the controller is manually
+ configured.
  .
  out-of-band: OpenFlow traffic uses a network separate from the data traffic
  that it controls.  If this is the case, the control network must already
  be configured on a network device other than one of those selected as
  an OpenFlow switch netdev in the previous question.
 
+Template: openflow-switch/discover
+Type: note
+_Description: Preparing to discover controller.
+ The setup program will now attempt to discover the OpenFlow controller.
+ Controller discovery may take up to 30 seconds.  Please be patient.
+ .
+ See secchan(8) for instructions on how to configure a DHCP server for
+ controller discovery.
+
+Template: openflow-switch/discovery-failure
+Type: error
+_Description: Controller discovery failed.
+ The controller's location could not be determined automatically.
+ .
+ Ensure that the OpenFlow DHCP server is properly configured.  See
+ secchan(8) for instructions on how to configure a DHCP server for
+ controller discovery.
+
+Template: openflow-switch/discovery-success
+Type: boolean
+Default: true
+_Description: Use discovered settings?
+ Controller discovery obtained the following settings:
+ .
+ Controller location: ${controller-vconn}
+ .
+ PKI URL: ${pki-uri}
+ .
+ Please verify that these settings are correct.
+
 Template: openflow-switch/switch-ip
 Type: string
 Default: dhcp
@@ -89,12 +124,16 @@ _Description: The controller location is invalid.
  connect to the controller over SSL (recommended for security) or
  "tcp:HOST[:PORT]" to connect over cleartext TCP.
 
-Template: openflow-switch/pki-host
+Template: openflow-switch/pki-uri
 Type: string
-_Description: OpenFlow PKI server host name:
- Specify the host name or IP address of the server that hosts the OpenFlow
- public key infrastructure (PKI).  This is usually the same host as the
- OpenFlow controller.
+_Description: OpenFlow PKI server host name or URL:
+ Specify a URL to the OpenFlow public key infrastructure (PKI).  If a
+ host name or IP address is specified in place of a URL, then
+ http://<host>/openflow/pki/ will be used,
+ where <host> is the specified host name or IP address.
+ .
+ The OpenFlow PKI is usually on the same machine as the OpenFlow
+ controller.
  .
  The setup process will connect to the OpenFlow PKI server over
  HTTP, using the system's configured default HTTP proxy (if any).
@@ -105,7 +144,7 @@ _Description: The switch CA certificate could not be retrieved.
  Retrieval of ${url} failed, with the following status: "${error}".
  .
  Ensure that the OpenFlow PKI server is correctly configured and
- available on ${pki-host}.  If the system is configured to use an HTTP
+ available at ${pki-uri}.  If the system is configured to use an HTTP
  proxy, also make sure that the HTTP proxy is available and that the
  PKI server can be reached through it.
 
@@ -147,7 +186,7 @@ _Description: The certificate request could not be sent.
  Posting to ${url} failed, with the following status: "${error}".
  .
  Ensure that the OpenFlow PKI server is correctly configured and
- available on ${pki-host}.
+ available at ${pki-uri}.
 
 Template: openflow-switch/fetch-switch-cert
 Type: select
@@ -179,7 +218,7 @@ _Description: Signed switch certificate could not be retrieved.
  .
  This probably indicates that the switch's certificate request has not
  yet been signed.  If this is the problem, it may be fixed by signing
- the certificate request at ${pki-host}, then trying to fetch the
+ the certificate request at ${pki-uri}, then trying to fetch the
  signed switch certificate again.
 
 Template: openflow-switch/complete
index 927eb09c721b179e84f3c4b58713ffe2ddc511eb..ffcc1e3fb1dc856009b933eb8a5972fff37c1a44 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: openflow-dev@lists.stanford.edu\n"
-"POT-Creation-Date: 2008-06-12 14:45-0700\n"
+"POT-Creation-Date: 2008-07-23 10:15-0700\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -101,21 +101,100 @@ msgid ""
 "configure the IP or IPv6 from these network devices."
 msgstr ""
 
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:4001
+msgid "Discover Controller Automatically?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:4001
+msgid ""
+"If the OpenFlow network includes a DHCP server that is configured "
+"appropriately, then the controller and PKI server can be discovered "
+"automatically."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:4001
+msgid "Controller discovery may take up to 30 seconds.  Please be patient."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:4001
+msgid ""
+"See secchan(8) for instructions on how to configure a DHCP server for "
+"controller discovery."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "Use discovered settings?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "Controller discovery obtained the following settings:"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "Controller location: ${controller-vconn}"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "PKI URL: ${pki-uri}"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "Please verify that these settings are correct."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:6001
+msgid "Controller discovery failed."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:6001
+msgid "The controller's location could not be determined automatically."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:6001
+msgid ""
+"Ensure that the OpenFlow DHCP server is properly configured.  See secchan(8) "
+"for instructions on how to configure a DHCP server for controller discovery."
+msgstr ""
+
 #. Type: select
 #. Choices
-#: ../openflow-switch.templates:4001
+#: ../openflow-switch.templates:7001
 msgid "in-band, out-of-band"
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:4002
+#: ../openflow-switch.templates:7002
 msgid "Switch-to-controller access method:"
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:4002
+#: ../openflow-switch.templates:7002
 msgid ""
 "The OpenFlow switch must be able to contact the OpenFlow controller over the "
 "network.  It can do so in one of two ways:"
@@ -123,7 +202,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:4002
+#: ../openflow-switch.templates:7002
 msgid ""
 "in-band: A single network is used for OpenFlow traffic and other data "
 "traffic; that is, the switch contacts the controller over one of the network "
@@ -133,7 +212,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:4002
+#: ../openflow-switch.templates:7002
 msgid ""
 "out-of-band: OpenFlow traffic uses a network separate from the data traffic "
 "that it controls.  If this is the case, the control network must already be "
@@ -143,13 +222,13 @@ msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:5001
+#: ../openflow-switch.templates:8001
 msgid "Switch IP address:"
 msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:5001
+#: ../openflow-switch.templates:8001
 msgid ""
 "For in-band communication with the controller, the OpenFlow switch must be "
 "able to determine its own IP address.  Its IP address may be configured "
@@ -158,13 +237,13 @@ msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:5001
+#: ../openflow-switch.templates:8001
 msgid "For static configuration, specify the switch's IP address as a string."
 msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:5001
+#: ../openflow-switch.templates:8001
 msgid ""
 "For dynamic configuration with DHCP (the most common case), specify \"dhcp"
 "\". Configuration with DHCP will only work reliably if the network topology "
@@ -174,13 +253,13 @@ msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:6001
+#: ../openflow-switch.templates:9001
 msgid "The switch IP address is invalid."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:6001
+#: ../openflow-switch.templates:9001
 msgid ""
 "The switch IP address must specified as \"dhcp\" or a valid IP address in "
 "dotted-octet form (e.g. \"1.2.3.4\")."
@@ -188,13 +267,13 @@ msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:7001
+#: ../openflow-switch.templates:10001
 msgid "Controller location:"
 msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:7001
+#: ../openflow-switch.templates:10001
 msgid ""
 "Specify how the OpenFlow switch should connect to the OpenFlow controller. "
 "The value should be in form \"ssl:HOST[:PORT]\" to connect to the controller "
@@ -204,13 +283,13 @@ msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:8001
+#: ../openflow-switch.templates:11001
 msgid "The controller location is invalid."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:8001
+#: ../openflow-switch.templates:11001
 msgid ""
 "The controller location must be specifed as \"ssl:HOST[:PORT]\" to connect "
 "to the controller over SSL (recommended for security) or \"tcp:HOST[:PORT]\" "
@@ -219,22 +298,30 @@ msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:9001
-msgid "OpenFlow PKI server host name:"
+#: ../openflow-switch.templates:12001
+msgid "OpenFlow PKI server host name or URL:"
 msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:9001
+#: ../openflow-switch.templates:12001
 msgid ""
-"Specify the host name or IP address of the server that hosts the OpenFlow "
-"public key infrastructure (PKI).  This is usually the same host as the "
-"OpenFlow controller."
+"Specify a URL to the OpenFlow public key infrastructure (PKI).  If a host "
+"name or IP address is specified in place of a URL, then http://<host>/"
+"openflow/pki/ will be used, where <host> is the specified host name or IP "
+"address."
 msgstr ""
 
 #. Type: string
 #. Description
-#: ../openflow-switch.templates:9001
+#: ../openflow-switch.templates:12001
+msgid ""
+"The OpenFlow PKI is usually on the same machine as the OpenFlow controller."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:12001
 msgid ""
 "The setup process will connect to the OpenFlow PKI server over HTTP, using "
 "the system's configured default HTTP proxy (if any)."
@@ -242,22 +329,22 @@ msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:10001
+#: ../openflow-switch.templates:13001
 msgid "The switch CA certificate could not be retrieved."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:10001
+#: ../openflow-switch.templates:13001
 msgid "Retrieval of ${url} failed, with the following status: \"${error}\"."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:10001
+#: ../openflow-switch.templates:13001
 msgid ""
-"Ensure that the OpenFlow PKI server is correctly configured and available on "
-"${pki-host}.  If the system is configured to use an HTTP proxy, also make "
+"Ensure that the OpenFlow PKI server is correctly configured and available at "
+"${pki-uri}.  If the system is configured to use an HTTP proxy, also make "
 "sure that the HTTP proxy is available and that the PKI server can be reached "
 "through it."
 msgstr ""
@@ -268,20 +355,20 @@ msgstr ""
 #. Choices
 #. Type: select
 #. Choices
-#: ../openflow-switch.templates:11001 ../openflow-switch.templates:12001
-#: ../openflow-switch.templates:14001
+#: ../openflow-switch.templates:14001 ../openflow-switch.templates:15001
+#: ../openflow-switch.templates:17001
 msgid "yes, no"
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:11002
+#: ../openflow-switch.templates:14002
 msgid "Is ${fingerprint} the controller CA's fingerprint?"
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:11002
+#: ../openflow-switch.templates:14002
 msgid ""
 "If a man-in-the-middle attack is possible in your network environment, check "
 "that the controller CA's fingerprint is really ${fingerprint}.  Answer \"yes"
@@ -290,7 +377,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:11002
+#: ../openflow-switch.templates:14002
 msgid ""
 "If a man-in-the-middle attack is not a concern, there is no need to verify "
 "the fingerprint.  Simply answer \"yes\"."
@@ -298,13 +385,13 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:12002
+#: ../openflow-switch.templates:15002
 msgid "Send certificate request to switch CA?"
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:12002
+#: ../openflow-switch.templates:15002
 msgid ""
 "Before it can connect to the controller over SSL, the OpenFlow switch's key "
 "must be signed by the switch certificate authority (CA) located on the "
@@ -314,7 +401,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:12002
+#: ../openflow-switch.templates:15002
 msgid ""
 "Answer \"yes\" to send a signing request to the switch CA now.  This is "
 "ordinarily the correct choice.  There is no harm in sending a given signing "
@@ -323,7 +410,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:12002
+#: ../openflow-switch.templates:15002
 msgid ""
 "Answer \"no\" to skip sending a signing request to the switch CA. Unless the "
 "request has already been sent to the switch CA, manual sending of the "
@@ -332,33 +419,33 @@ msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:13001
+#: ../openflow-switch.templates:16001
 msgid "The certificate request could not be sent."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:13001
+#: ../openflow-switch.templates:16001
 msgid "Posting to ${url} failed, with the following status: \"${error}\"."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:13001
+#: ../openflow-switch.templates:16001
 msgid ""
-"Ensure that the OpenFlow PKI server is correctly configured and available on "
-"${pki-host}."
+"Ensure that the OpenFlow PKI server is correctly configured and available at "
+"${pki-uri}."
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:14002
+#: ../openflow-switch.templates:17002
 msgid "Fetch signed switch certificate from PKI server?"
 msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:14002
+#: ../openflow-switch.templates:17002
 msgid ""
 "Before it can connect to the controller over SSL, the OpenFlow switch's key "
 "must be signed by the switch certificate authority (CA) located on the "
@@ -368,7 +455,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:14002
+#: ../openflow-switch.templates:17002
 msgid ""
 "At this point, a signing request has been sent to the switch CA (or sending "
 "a request has been manually skipped), but the signed certificate has not yet "
@@ -378,7 +465,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:14002
+#: ../openflow-switch.templates:17002
 msgid ""
 "Answer \"yes\" to attempt to retrieve the signed switch certificate from the "
 "switch CA.  If the switch certificate request has been signed at the PKI "
@@ -387,7 +474,7 @@ msgstr ""
 
 #. Type: select
 #. Description
-#: ../openflow-switch.templates:14002
+#: ../openflow-switch.templates:17002
 msgid ""
 "Answer \"no\" to postpone switch configuration.  The configuration process "
 "must be restarted later, when the switch certificate request has been signed."
@@ -395,13 +482,13 @@ msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:15001
+#: ../openflow-switch.templates:18001
 msgid "Signed switch certificate could not be retrieved."
 msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:15001
+#: ../openflow-switch.templates:18001
 msgid ""
 "The signed switch certificate could not be retrieved from the switch CA: "
 "retrieval of ${url} failed, with the following status: \"${error}\"."
@@ -409,23 +496,23 @@ msgstr ""
 
 #. Type: error
 #. Description
-#: ../openflow-switch.templates:15001
+#: ../openflow-switch.templates:18001
 msgid ""
 "This probably indicates that the switch's certificate request has not yet "
 "been signed.  If this is the problem, it may be fixed by signing the "
-"certificate request at ${pki-host}, then trying to fetch the signed switch "
+"certificate request at ${pki-uri}, then trying to fetch the signed switch "
 "certificate again."
 msgstr ""
 
 #. Type: note
 #. Description
-#: ../openflow-switch.templates:16001
+#: ../openflow-switch.templates:19001
 msgid "OpenFlow Switch Setup Finished"
 msgstr ""
 
 #. Type: note
 #. Description
-#: ../openflow-switch.templates:16001
+#: ../openflow-switch.templates:19001
 msgid ""
 "Setup of this OpenFlow switch is finished.  Complete the setup procedure to "
 "enable the switch."
index d427bb0d2a90a0d2df6136d0c4a66023f86a9268..2d00f0261a017d3262dcf2d220360c04878cc3fd 100644 (file)
@@ -193,7 +193,8 @@ const char *dhcp_type_name(enum dhcp_msg_type);
     DHCP_OPT(T2,                       59, SECS,    1, 1)               \
     DHCP_OPT(VENDOR_CLASS,             60, STRING,  1, SIZE_MAX)        \
     DHCP_OPT(CLIENT_ID,                61, UINT8,   2, SIZE_MAX)        \
-    DHCP_VNDOPT(OFP_CONTROLLER_VCONN,   1, STRING,  1, SIZE_MAX)
+    DHCP_VNDOPT(OFP_CONTROLLER_VCONN,   1, STRING,  1, SIZE_MAX)        \
+    DHCP_VNDOPT(OFP_PKI_URI,            2, STRING,  1, SIZE_MAX)
 
 /* Shorthand for defining vendor options (used above). */
 #define DHCP_VNDOPT(NAME, CODE, ARG, MIN, MAX) \
index 434062353ab9720e955a3d5f308c6a47973cf71d..7cf17695e19bb55b4fbd203dac9188dcaeda1da8 100644 (file)
@@ -76,6 +76,12 @@ vendor-specific option with code 1 whose contents are a string
 specifying the location of the controller in the same format used on
 the \fBsecchan\fR command line (e.g. \fBssl:192.168.0.1\fR).
 
+The DHCP reply may also, optionally, include a vendor-specific option
+with code 2 whose contents are a string specifying the URI to the base
+of the OpenFlow PKI (e.g. \fBhttp://192.168.0.1/openflow/pki\fR).
+This URI is used only for bootstrapping the OpenFlow PKI at initial
+switch setup; \fBsecchan\fR does not use it at all.
+
 The following ISC DHCP server configuration file assigns the IP
 address range 192.168.0.20 through 192.168.0.30 to OpenFlow switches
 that follow the switch protocol and addresses 192.168.0.1 through
@@ -89,6 +95,8 @@ option space openflow;
 .br
 option openflow.controller-vconn code 1 = text;
 .br
+option openflow.pki-uri code 2 = text;
+.br
 class "OpenFlow" {
 .br
   match if option vendor-class-identifier = "OpenFlow";
@@ -96,6 +104,8 @@ class "OpenFlow" {
   vendor-option-space openflow;
 .br
   option openflow.controller-vconn "tcp:192.168.0.10";
+.br
+  option openflow.pki-uri "http://192.168.0.10/openflow/pki";
 .br
   option vendor-class-identifier "OpenFlow";
 .br