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');
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', $_) },
$req_fingerprint = sha1_hex($req);
}
+my %options;
+
my (@states) =
(sub {
# User backed up from first dialog box.
}
},
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();
}
},
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';
}
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;
},
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';
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';
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;
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();
}
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';
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();
}
}
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 {
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";
sub shell_escape {
local $_ = $_[0];
- if (m&^[-a-zA-Z0-9:./%^_+,]*$&) {
+ if ($_ eq '') {
+ return '""';
+ } elsif (m&^[-a-zA-Z0-9:./%^_+,]*$&) {
return $_;
} else {
s/'/'\\''/;
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:/);
+}
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.
# 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.
# 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.
# 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.
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
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
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
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
_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
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
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
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).
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.
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
.
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
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"
"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:"
#. 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 "
#. 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 "
#. 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 "
#. 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 "
#. 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\")."
#. 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 "
#. 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]\" "
#. 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)."
#. 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 ""
#. 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"
#. 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\"."
#. 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 "
#. 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 "
#. 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 "
#. 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 "
#. 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 "
#. 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 "
#. 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."
#. 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}\"."
#. 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."
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) \
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
.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";
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