From df3a28bf74a70ef3570829d1e67b96f7d982d693 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 23 Jul 2008 13:11:00 -0700 Subject: [PATCH] Support controller discovery in Debian packages. --- debian/ofp-switch-setup | 162 +++++++++++++++---- debian/openflow-controller.README.Debian | 7 +- debian/openflow-switch.default | 31 ++-- debian/openflow-switch.init | 67 ++++---- debian/openflow-switch.install | 2 + debian/openflow-switch.manpages | 2 + debian/openflow-switch.templates | 71 +++++++-- debian/po/templates.pot | 193 ++++++++++++++++------- include/dhcp.h | 3 +- secchan/secchan.8.in | 10 ++ 10 files changed, 406 insertions(+), 142 deletions(-) diff --git a/debian/ofp-switch-setup b/debian/ofp-switch-setup index 0c03c332..74f3f87d 100755 --- a/debian/ofp-switch-setup +++ b/debian/ofp-switch-setup @@ -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 () { + 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:/); +} diff --git a/debian/openflow-controller.README.Debian b/debian/openflow-controller.README.Debian index c54e5699..19d5cb9b 100644 --- a/debian/openflow-controller.README.Debian +++ b/debian/openflow-controller.README.Debian @@ -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. diff --git a/debian/openflow-switch.default b/debian/openflow-switch.default index f2ce5a6a..e4fb07bc 100644 --- a/debian/openflow-switch.default +++ b/debian/openflow-switch.default @@ -21,13 +21,18 @@ # 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 @@ -35,13 +40,12 @@ # 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. diff --git a/debian/openflow-switch.init b/debian/openflow-switch.init index 1f03df10..74412d90 100755 --- a/debian/openflow-switch.init +++ b/debian/openflow-switch.init @@ -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 diff --git a/debian/openflow-switch.install b/debian/openflow-switch.install index 77ea13af..2c851361 100644 --- a/debian/openflow-switch.install +++ b/debian/openflow-switch.install @@ -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 diff --git a/debian/openflow-switch.manpages b/debian/openflow-switch.manpages index 9f4c4ff8..b012d8db 100644 --- a/debian/openflow-switch.manpages +++ b/debian/openflow-switch.manpages @@ -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 diff --git a/debian/openflow-switch.templates b/debian/openflow-switch.templates index c6d4b5e4..78761097 100644 --- a/debian/openflow-switch.templates +++ b/debian/openflow-switch.templates @@ -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:///openflow/pki/ will be used, + where 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 diff --git a/debian/po/templates.pot b/debian/po/templates.pot index 927eb09c..ffcc1e3f 100644 --- a/debian/po/templates.pot +++ b/debian/po/templates.pot @@ -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 \n" "Language-Team: LANGUAGE \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:///" +"openflow/pki/ will be used, where 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." diff --git a/include/dhcp.h b/include/dhcp.h index d427bb0d..2d00f026 100644 --- a/include/dhcp.h +++ b/include/dhcp.h @@ -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) \ diff --git a/secchan/secchan.8.in b/secchan/secchan.8.in index 43406235..7cf17695 100644 --- a/secchan/secchan.8.in +++ b/secchan/secchan.8.in @@ -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 -- 2.30.2