AC_PROG_CPP
AC_PROG_LD
+AC_ARG_VAR([PERL], [path to Perl interpreter])
+AC_PATH_PROG([PERL], perl, no)
+if test "$PERL" = no; then
+ AC_MSG_ERROR([Perl interpreter not found in $PATH or $PERL.])
+fi
+
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_LIBTOOL
--- /dev/null
+*.debhelper
+/files
+/openflow
+/openflow-common
+/openflow-controller
+/openflow-pki
+/openflow-switch
+/openflow-datapath-source
+*.substvars
--- /dev/null
+openflow (0.8.1) unstable; urgency=low
+
+ * Development version.
+
+ -- OpenFlow team <openflow-dev@lists.stanford.edu> Mon, 19 Nov 2007 14:57:52 -0800
--- /dev/null
+Source: openflow
+Section: net
+Priority: extra
+Maintainer: OpenFlow Team <openflow-dev@lists.stanford.edu>
+Build-Depends: debhelper (>= 5), autoconf (>= 2.60), automake1.10, libssl-dev, pkg-config (>= 0.21), po-debconf, bzip2
+Standards-Version: 3.7.3
+
+Package: openflow-datapath-source
+Architecture: all
+Depends: module-assistant, bzip2, debhelper (>= 5.0.37)
+Suggests: openflow-switch
+Description: Source code for OpenFlow datapath Linux module
+ This package provides the OpenFlow datapath module source code that
+ is needed by the kernel-based OpenFlow switch. The kernel module can
+ be built from it using module-assistant or make-kpkg. README.Debian
+ in this package provides further instructions.
+ .
+ OpenFlow is a protocol for flow-based control over network switching.
+
+Package: openflow-common
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: OpenFlow common components
+ openflow-common provides components required by both openflow-switch
+ and openflow-controller.
+ .
+ OpenFlow is a protocol for flow-based control over network switching.
+
+Package: openflow-switch
+Architecture: any
+Suggests: openflow-datapath-module
+Depends: ${shlibs:Depends}, ${misc:Depends}, openflow-common, libwww-perl, libdigest-sha1-perl, dhcp3-client
+Description: OpenFlow switch implementations
+ openflow-switch provides the userspace components and utilities for
+ the OpenFlow kernel-based switch. It also includes a userspace-only
+ implementation of an OpenFlow switch.
+ .
+ OpenFlow is a protocol for flow-based control over network switching.
+
+Package: openflow-pki
+Architecture: all
+Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2
+Description: OpenFlow public key infrastructure
+ openflow-pki provides PKI (public key infrastructure) support for
+ OpenFlow switches and controllers, reducing the risk of
+ man-in-the-middle attacks on the OpenFlow network infrastructure.
+ .
+ OpenFlow is a protocol for flow-based control over network switching.
+
+Package: openflow-controller
+Architecture: any
+Depends: ${shlibs:Depends}, openflow-common, openflow-pki
+Description: OpenFlow controller implementation
+ The OpenFlow controller enables OpenFlow switches that connect to it
+ to act as MAC-learning Ethernet switches.
+ .
+ OpenFlow is a protocol for flow-based control over network switching.
--- /dev/null
+Source: openflow
+Section: net
+Priority: extra
+Maintainer: OpenFlow Team <openflow-dev@lists.stanford.edu>
+Build-Depends: debhelper (>= 5.0.37)
+Standards-Version: 3.7.3
+
+Package: openflow-datapath-module-_KVERS_
+Architecture: any
+Recommends: kernel-image-_KVERS_, openflow-switch
+Provides: openflow-datapath-module
+Description: OpenFlow Linux datapath kernel module
+ This package contains the OpenFlow loadable datapath kernel modules for
+ the kernel-image-_KVERS_ package.
+ .
+ If you compiled a custom kernel, you will most likely need to compile
+ a custom version of this module as well. The openflow-datapath-source
+ package has been provided for this purpose. Refer to README.Debian
+ provided in that package for further instructions.
--- /dev/null
+Upstream Authors:
+
+ The Board of Trustees of The Leland Stanford Junior University
+
+Copyright:
+
+ Copyright (C) 2008 The Board of Trustees of The Leland Stanford
+ Junior University
+
+License:
+
+ We are making the OpenFlow specification and associated documentation
+ (Software) available for public use and benefit with the expectation
+ that others will use, modify and enhance the Software and contribute
+ those enhancements back to the community. However, since we would like
+ to make the Software available for broadest use, with as few
+ restrictions as possible permission is hereby granted, free of charge,
+ to any person obtaining a copy of this Software to deal in the Software
+ under the copyrights without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ The name and trademarks of copyright holder(s) may NOT be used in
+ advertising or publicity pertaining to the Software or any derivatives
+ without specific, written prior permission.
+
--- /dev/null
+usr/bin
+usr/sbin
--- /dev/null
+#! /usr/bin/perl
+
+use POSIX;
+use Debconf::Client::ConfModule ':all';
+use HTTP::Request;
+use LWP::UserAgent;
+use Digest::SHA1 'sha1_hex';
+use strict;
+use warnings;
+
+my $debconf_owner = 'openflow-switch';
+
+my $default = '/etc/default/openflow-switch';
+my $etc = '/etc/openflow-switch';
+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 $ua = LWP::UserAgent->new;
+$ua->timeout(10);
+$ua->env_proxy;
+
+version('2.0');
+capb('backup');
+title('OpenFlow Switch Setup');
+
+my (%netdevs) = find_netdevs();
+db_subst('netdevs', 'choices',
+ join(', ', map($netdevs{$_}, sort(keys(%netdevs)))));
+db_set('netdevs', join(', ', grep(!/IP/, values(%netdevs))));
+
+if (-e $default) {
+ my (%config) = load_config($default);
+
+ my (%map) =
+ (NETDEVS => sub {
+ db_set('netdevs', join(', ', map($netdevs{$_},
+ grep(exists $netdevs{$_}, split))))
+ },
+ IN_BAND => sub {
+ db_set('band', $_ eq 'no' ? 'in-band' : 'out-of-band')
+ },
+ SWITCH_IP => sub { db_set('switch-ip', $_) },
+ CONTROLLER => sub { db_set('controller-vconn', $_) },
+ PRIVKEY => sub { $privkey_file = $_ },
+ CERT => sub { $cert_file = $_ },
+ CACERT => sub { $cacert_file = $_ },
+ );
+
+ for my $key (keys(%map)) {
+ local $_ = $config{$key};
+ &{$map{$key}}() if defined && !/^\s*$/;
+ }
+}
+
+my $cacert_preverified = -e $cacert_file;
+
+if (! -e $privkey_file) {
+ my $old_umask = umask(077);
+ run_cmd("ofp-pki req $etc/of0 >&2 2>/dev/null");
+ chmod(0644, $req_file) or die "$req_file: chmod: $!\n";
+ umask($old_umask);
+}
+
+my ($req, $req_fingerprint);
+if (! -e $cert_file) {
+ open(REQ, '<', $req_file) or die "$req_file: open: $!\n";
+ $req = join('', <REQ>);
+ close(REQ);
+ $req_fingerprint = sha1_hex($req);
+}
+
+my (@states) =
+ (sub {
+ # User backed up from first dialog box.
+ exit(10);
+ },
+ sub {
+ # Prompt for ports to include in switch.
+ db_input('netdevs');
+ return;
+ },
+ sub {
+ # Validate the chosen ports.
+ my (@netdevs) = split(', ', db_get('netdevs'));
+ if (!@netdevs) {
+ # No ports chosen. Disable switch.
+ db_input('no-netdevs');
+ return 'prev' if db_go();
+ return 'done';
+ } elsif (my (@conf_netdevs) = grep(/IP/, @netdevs)) {
+ # Point out that some ports have configured IP addresses.
+ db_subst('configured-netdevs', 'configured-netdevs',
+ join(', ', @conf_netdevs));
+ db_input('configured-netdevs');
+ return;
+ } else {
+ # Otherwise proceed.
+ return 'skip';
+ }
+ },
+ sub {
+ # In-band or out-of-band controller?
+ db_input('band');
+ return;
+ },
+ sub {
+ return 'skip' if db_get('band') eq 'out-of-band';
+ for (;;) {
+ db_input('switch-ip');
+ return 'prev' if db_go();
+
+ my $ip = db_get('switch-ip');
+ return 'next' if $ip =~ /^dhcp|\d+\.\d+.\d+.\d+$/i;
+
+ db_input('switch-ip-error');
+ db_go();
+ }
+ },
+ sub {
+ 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);
+ }
+ return 'next';
+ }
+
+ db_input('controller-vconn-error');
+ db_go();
+ }
+ },
+ sub {
+ return 'skip' if !ssl_enabled();
+ return 'skip' if -e $cacert_file && -e $cert_file;
+
+ db_input('pki-host');
+ return 'prev' if db_go();
+ return;
+ },
+ sub {
+ 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 $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_input('fetch-cacert-failed');
+ db_go();
+ return 'prev';
+ },
+ sub {
+ return 'skip' if !ssl_enabled();
+ return 'skip' if -e $cert_file;
+
+ for (;;) {
+ db_set('send-cert-req', 'yes');
+ db_input('send-cert-req');
+ 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 $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_input('send-cert-req-failed');
+ db_go();
+ }
+ },
+ sub {
+ return 'skip' if !ssl_enabled();
+ return 'skip' if $cacert_preverified;
+
+ my ($cacert_fingerprint) = x509_fingerprint($cacert_file);
+ db_subst('verify-controller-ca', 'fingerprint', $cacert_fingerprint);
+ db_input('verify-controller-ca');
+ return 'prev' if db_go();
+ return 'next' if db_get('verify-controller-ca') eq 'yes';
+ unlink($cacert_file);
+ return 'prev';
+ },
+ sub {
+ return 'skip' if !ssl_enabled();
+ return 'skip' if -e $cert_file;
+
+ for (;;) {
+ db_set('fetch-switch-cert', 'yes');
+ db_input('fetch-switch-cert');
+ 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 $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_input('fetch-switch-cert-failed');
+ db_go();
+ }
+ },
+ sub {
+ db_input('complete');
+ db_go();
+ return;
+ },
+ sub {
+ return 'done';
+ },
+);
+
+my $state = 1;
+my $direction = 1;
+for (;;) {
+ my $ret = &{$states[$state]}();
+ $ret = db_go() ? 'prev' : 'next' if !defined $ret;
+ if ($ret eq 'next') {
+ $direction = 1;
+ } elsif ($ret eq 'prev') {
+ $direction = -1;
+ } elsif ($ret eq 'skip') {
+ # Nothing to do.
+ } elsif ($ret eq 'done') {
+ last;
+ } else {
+ die "unknown ret $ret";
+ }
+ $state += $direction;
+}
+
+my %config;
+$config{NETDEVS} = join(' ', map(/^(\S+)/, split(', ', db_get('netdevs'))));
+if (db_get('band') eq 'in-band') {
+ $config{IN_BAND} = 'yes';
+ $config{SWITCH_IP} = db_get('switch-ip');
+} else {
+ $config{IN_BAND} = 'no';
+}
+$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");
+
+sub ssl_enabled {
+ return db_get('controller-vconn') =~ /^ssl:/;
+}
+
+sub db_subst {
+ my ($question, $key, $value) = @_;
+ $question = "$debconf_owner/$question";
+ my ($ret, $seen) = subst($question, $key, $value);
+ if ($ret && $ret != 30) {
+ die "Error substituting $value for $key in debconf question "
+ . "$question: $seen";
+ }
+}
+
+sub db_set {
+ my ($question, $value) = @_;
+ $question = "$debconf_owner/$question";
+ my ($ret, $seen) = set($question, $value);
+ if ($ret && $ret != 30) {
+ die "Error setting debconf question $question to $value: $seen";
+ }
+}
+
+sub db_get {
+ my ($question) = @_;
+ $question = "$debconf_owner/$question";
+ my ($ret, $seen) = get($question);
+ if ($ret) {
+ die "Error getting debconf question $question answer: $seen";
+ }
+ return $seen;
+}
+
+sub db_fset {
+ my ($question, $flag, $value) = @_;
+ $question = "$debconf_owner/$question";
+ my ($ret, $seen) = fset($question, $flag, $value);
+ if ($ret && $ret != 30) {
+ die "Error setting debconf question $question flag $flag to $value: "
+ . "$seen";
+ }
+}
+
+sub db_fget {
+ my ($question, $flag) = @_;
+ $question = "$debconf_owner/$question";
+ my ($ret, $seen) = fget($question, $flag);
+ if ($ret) {
+ die "Error getting debconf question $question flag $flag: $seen";
+ }
+ return $seen;
+}
+
+sub db_input {
+ my ($question) = @_;
+ db_fset($question, "seen", "false");
+
+ $question = "$debconf_owner/$question";
+ my ($ret, $seen) = input('high', $question);
+ if ($ret && $ret != 30) {
+ die "Error requesting debconf question $question: $seen";
+ }
+ return $ret;
+}
+
+sub db_go {
+ my ($ret, $seen) = go();
+ if (!defined($ret)) {
+ exit(1); # Cancel button was pushed.
+ }
+ if ($ret && $ret != 30) {
+ die "Error asking debconf questions: $seen";
+ }
+ return $ret;
+}
+
+sub run_cmd {
+ my ($cmd) = @_;
+ return if system($cmd) == 0;
+
+ if ($? == -1) {
+ die "$cmd: failed to execute: $!\n";
+ } elsif ($? & 127) {
+ die sprintf("$cmd: child died with signal %d, %s coredump\n",
+ ($? & 127), ($? & 128) ? 'with' : 'without');
+ } else {
+ die sprintf("$cmd: child exited with value %d\n", $? >> 8);
+ }
+}
+
+sub x509_fingerprint {
+ my ($file) = @_;
+ my $cmd = "openssl x509 -noout -in $file -fingerprint";
+ open(OPENSSL, '-|', $cmd) or die "$cmd: failed to execute: $!\n";
+ my $line = <OPENSSL>;
+ close(OPENSSL);
+ my ($fingerprint) = $line =~ /SHA1 Fingerprint=(.*)/;
+ return $line if !defined $fingerprint;
+ $fingerprint =~ s/://g;
+ return $fingerprint;
+}
+
+sub find_netdevs {
+ my ($netdev, %netdevs);
+ open(IFCONFIG, "/sbin/ifconfig -a|") or die "ifconfig failed: $!";
+ while (<IFCONFIG>) {
+ if (my ($nd) = /^([^\s]+)/) {
+ $netdev = $nd;
+ $netdevs{$netdev} = "$netdev";
+ if (my ($hwaddr) = /HWaddr (\S+)/) {
+ $netdevs{$netdev} .= " (MAC: $hwaddr)";
+ }
+ } elsif (my ($ip4) = /^\s*inet addr:(\S+)/) {
+ $netdevs{$netdev} .= " (IP: $ip4)";
+ } elsif (my ($ip6) = /^\s*inet6 addr:(\S+)/) {
+ $netdevs{$netdev} .= " (IPv6: $ip6)";
+ }
+ }
+ foreach my $nd (keys(%netdevs)) {
+ delete $netdevs{$nd} if $nd eq 'lo' || $nd =~ /^wmaster/;
+ }
+ close(IFCONFIG);
+ return %netdevs;
+}
+
+sub load_config {
+ my ($file) = @_;
+ my ($cmd) = "set -a && . $file && env";
+ if (!open(VARS, '-|', $cmd)) {
+ print STDERR "$cmd: failed to execute: $!\n";
+ return;
+ }
+ my (%config);
+ while (<VARS>) {
+ my ($var, $value) = /^([^=]+)=(.*)$/ or next;
+ $config{$var} = $value;
+ }
+ close(VARS);
+ return %config;
+}
+
+sub shell_escape {
+ local $_ = $_[0];
+ if (m&^[-a-zA-Z0-9:./%^_+,]*$&) {
+ return $_;
+ } else {
+ s/'/'\\''/;
+ return "'$_'";
+ }
+}
+
+sub shell_assign {
+ my ($var, $value) = @_;
+ return $var . '=' . shell_escape($value);
+}
+
+sub save_config {
+ my ($file, %config) = @_;
+ my (@lines);
+ if (open(FILE, '<', $file)) {
+ @lines = <FILE>;
+ chomp @lines;
+ close(FILE);
+ }
+
+ # Replace all existing variable assignments.
+ for (my ($i) = 0; $i <= $#lines; $i++) {
+ local $_ = $lines[$i];
+ my ($var, $value) = /^\s*([^=#]+)=(.*)$/ or next;
+ if (exists($config{$var})) {
+ $lines[$i] = shell_assign($var, $config{$var});
+ delete $config{$var};
+ } else {
+ $lines[$i] = "#$lines[$i]";
+ }
+ }
+
+ # Find a place to put any remaining variable assignments.
+ VAR:
+ for my $var (keys(%config)) {
+ my $assign = shell_assign($var, $config{$var});
+
+ # Replace the last commented-out variable assignment to $var, if any.
+ for (my ($i) = $#lines; $i >= 0; $i--) {
+ local $_ = $lines[$i];
+ if (/^\s*#\s*$var=/) {
+ $lines[$i] = $assign;
+ next VAR;
+ }
+ }
+
+ # Find a place to add the var: after the final commented line
+ # just after a line that contains "$var:".
+ for (my ($i) = 0; $i <= $#lines; $i++) {
+ if ($lines[$i] =~ /^\s*#\s*$var:/) {
+ for (my ($j) = $i + 1; $j <= $#lines; $j++) {
+ if ($lines[$j] !~ /^\s*#/) {
+ splice(@lines, $j, 0, $assign);
+ next VAR;
+ }
+ }
+ }
+ }
+
+ # Just append it.
+ push(@lines, $assign);
+ }
+
+ open(NEWFILE, '>', "$file.tmp") or die "$file.tmp: create: $!\n";
+ print NEWFILE join('', map("$_\n", @lines));
+ close(NEWFILE);
+ rename("$file.tmp", $file) or die "$file.tmp: rename to $file: $!\n";
+}
--- /dev/null
+.TH ofp-switch-setup 8 "June 2008" "OpenFlow" "OpenFlow Manual"
+
+.SH NAME
+ofp\-switch\-setup \- interactive setup for OpenFlow switch
+
+.SH SYNOPSIS
+.B ofp\-switch\-setup
+
+.SH DESCRIPTION
+The \fBofp\-switch\-setup\fR program is an interactive program that
+assists the system administrator in configuring an OpenFlow switch,
+including the underlying public key infrastructure (PKI).
+
+.SH OPTIONS
+ofp\-switch\-setup does not accept any command-line options.
+
+.SH FILES
+.IP /etc/default/openflow-switch
+Main configuration file for OpenFlow switch.
+
+.IP /etc/openflow-switch/cacert.pem
+Default location of CA certificate for OpenFlow controllers.
+
+.IP /etc/openflow-switch/of0-cert.pem
+Default location of certificate for the OpenFlow switch's private key.
+
+.IP /etc/openflow-switch/of0-privkey.pem
+Default location of the OpenFlow switch's private key. This file
+should be readable only by \fBroot\fR.
+
+.IP /etc/openflow-switch/of0-req.pem
+Default location of certificate request for the OpenFlow switch's
+certificate. This file is not used after the signed certificate
+(typically \fB/etc/openflow-switch/of0-cert.pem\fR, above) has been
+obtained from the OpenFlow PKI server.
+
+.SH "SEE ALSO"
+
+.BR ofp-pki (8),
+.BR dpctl (8),
+.BR secchan (8)
--- /dev/null
+utilities/ofp-pki usr/sbin
+utilities/vlogconf usr/sbin
--- /dev/null
+utilities/vlogconf.8
+utilities/ofp-pki.8
--- /dev/null
+README.Debian for openflow-controller
+-------------------------------------
+
+* To reconfigure the controller, edit /etc/default/openflow-controller
+ and run "/etc/init.d/openflow-controller restart".
--- /dev/null
+# This is a POSIX shell fragment -*- sh -*-
+
+# LISTEN: What OpenFlow connection methods should the controller listen on?
+#
+# This is a space-delimited list of connection methods:
+#
+# * "pssl:[PORT]": Listen for SSL connections on the specified PORT
+# (default: 976). The private key, certificate, and CA certificate
+# must be specified below.
+#
+# * "pctp:[PORT]": Listen for TCP connections on the specified PORT
+# (default: 975). Not recommended for security reasons.
+#
+# * "nl:DP_IDX": Listen on local datapath DP_IDX. Used only if this
+# machine is also an OpenFlow switch and not running the secure
+# channel, and only if you know what you're doing.
+#
+LISTEN="pssl:"
+
+# PRIVKEY: Name of file containing controller's private key.
+# Required if SSL enabled.
+PRIVKEY=/etc/openflow-controller/privkey.pem
+
+# CERT: Name of file containing certificate for private key.
+# Required if SSL enabled.
+CERT=/etc/openflow-controller/cert.pem
+
+# CACERT: Name of file containing switch CA certificate.
+# Required if SSL enabled.
+CACERT=/etc/openflow-controller/cacert.pem
+
+# Additional options to pass to controller, e.g. "--hub"
+DAEMON_OPTS=""
--- /dev/null
+etc/openflow-controller
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2007 Javier Fernandez-Sanguino <jfs@debian.org>
+#
+# This is free software; you may redistribute it and/or modify
+# it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2,
+# or (at your option) any later version.
+#
+# This is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License with
+# the Debian operating system, in /usr/share/common-licenses/GPL; if
+# not, write to the Free Software Foundation, Inc., 59 Temple Place,
+# Suite 330, Boston, MA 02111-1307 USA
+#
+### BEGIN INIT INFO
+# Provides: openflow-controller
+# Required-Start: $network $local_fs
+# Required-Stop:
+# Should-Start: $named
+# Should-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: OpenFlow controller
+### END INIT INFO
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+DAEMON=/usr/sbin/controller # Introduce the server's location here
+NAME=controller # Introduce the short server's name here
+DESC=controller # Introduce a short description here
+LOGDIR=/var/log/openflow # Log directory to use
+
+PIDFILE=/var/run/$NAME.pid
+
+test -x $DAEMON || exit 0
+
+. /lib/lsb/init-functions
+
+# Default options, these can be overriden by the information
+# at /etc/default/$NAME
+DAEMON_OPTS="" # Additional options given to the server
+
+DODTIME=10 # Time to wait for the server to die, in seconds
+ # If this value is set too low you might not
+ # let some servers to die gracefully and
+ # 'restart' will not work
+
+LOGFILE=$LOGDIR/$NAME.log # Server logfile
+#DAEMONUSER= # User to run the daemons as. If this value
+ # is set start-stop-daemon will chuid the server
+
+# Include defaults if available
+default=/etc/default/openflow-controller
+if [ -f $default ] ; then
+ . $default
+fi
+
+# Check that the user exists (if we set a user)
+# Does the user exist?
+if [ -n "$DAEMONUSER" ] ; then
+ if getent passwd | grep -q "^$DAEMONUSER:"; then
+ # Obtain the uid and gid
+ DAEMONUID=`getent passwd |grep "^$DAEMONUSER:" | awk -F : '{print $3}'`
+ DAEMONGID=`getent passwd |grep "^$DAEMONUSER:" | awk -F : '{print $4}'`
+ else
+ log_failure_msg "The user $DAEMONUSER, required to run $NAME does not exist."
+ exit 1
+ fi
+fi
+
+
+set -e
+
+running_pid() {
+# Check if a given process pid's cmdline matches a given name
+ pid=$1
+ name=$2
+ [ -z "$pid" ] && return 1
+ [ ! -d /proc/$pid ] && return 1
+ cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
+ # Is this the expected server
+ [ "$cmd" != "$name" ] && return 1
+ return 0
+}
+
+running() {
+# Check if the process is running looking at /proc
+# (works for all users)
+
+ # No pidfile, probably no daemon present
+ [ ! -f "$PIDFILE" ] && return 1
+ pid=`cat $PIDFILE`
+ running_pid $pid $DAEMON || return 1
+ return 0
+}
+
+start_server() {
+ if [ -z "$LISTEN" ]; then
+ echo "$default: No connection methods configured, controller disabled" >&2
+ exit 0
+ fi
+
+ SSL_OPTS=
+ case $LISTEN in
+ *ssl*)
+ : ${PRIVKEY:=/etc/openflow-controller/privkey.pem}
+ : ${CERT:=/etc/openflow-controller/cert.pem}
+ : ${CACERT:=/etc/openflow-controller/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
+ exit 1
+ fi
+ SSL_OPTS="--private-key=$PRIVKEY --certificate=$CERT --ca-cert=$CACERT"
+ ;;
+ esac
+
+# Start the process using the wrapper
+ if [ -z "$DAEMONUSER" ] ; then
+ start-stop-daemon --start --pidfile $PIDFILE \
+ --exec $DAEMON -- --detach --pidfile=$PIDFILE \
+ $LISTEN $DAEMON_OPTS $SSL_OPTS
+ errcode=$?
+ else
+# if we are using a daemonuser then change the user id
+ start-stop-daemon --start --quiet --pidfile $PIDFILE \
+ --chuid $DAEMONUSER --exec $DAEMON -- \
+ --detach --pidfile=$PIDFILE $LISTEN $DAEMON_OPTS \
+ $SSL_OPTS
+ errcode=$?
+ fi
+ return $errcode
+}
+
+stop_server() {
+# Stop the process using the wrapper
+ if [ -z "$DAEMONUSER" ] ; then
+ start-stop-daemon --stop --quiet --pidfile $PIDFILE \
+ --exec $DAEMON
+ errcode=$?
+ else
+# if we are using a daemonuser then look for process that match
+ start-stop-daemon --stop --quiet --pidfile $PIDFILE \
+ --user $DAEMONUSER --exec $DAEMON
+ errcode=$?
+ fi
+
+ return $errcode
+}
+
+reload_server() {
+ [ ! -f "$PIDFILE" ] && return 1
+ pid=`cat $PIDFILE` # This is the daemon's pid
+ # Send a SIGHUP
+ kill -1 $pid
+ return $?
+}
+
+force_stop() {
+# Force the process to die killing it manually
+ [ ! -e "$PIDFILE" ] && return
+ if running ; then
+ kill -15 $pid
+ # Is it really dead?
+ sleep "$DIETIME"s
+ if running ; then
+ kill -9 $pid
+ sleep "$DIETIME"s
+ if running ; then
+ echo "Cannot kill $NAME (pid=$pid)!"
+ exit 1
+ fi
+ fi
+ fi
+ rm -f $PIDFILE
+}
+
+
+case "$1" in
+ start)
+ log_daemon_msg "Starting $DESC " "$NAME"
+ # Check if it's running first
+ if running ; then
+ log_progress_msg "apparently already running"
+ log_end_msg 0
+ exit 0
+ fi
+ if start_server && running ; then
+ # It's ok, the server started and is running
+ log_end_msg 0
+ else
+ # Either we could not start it or it is not running
+ # after we did
+ # NOTE: Some servers might die some time after they start,
+ # this code does not try to detect this and might give
+ # a false positive (use 'status' for that)
+ log_end_msg 1
+ fi
+ ;;
+ stop)
+ log_daemon_msg "Stopping $DESC" "$NAME"
+ if running ; then
+ # Only stop the server if we see it running
+ stop_server
+ log_end_msg $?
+ else
+ # If it's not running don't do anything
+ log_progress_msg "apparently not running"
+ log_end_msg 0
+ exit 0
+ fi
+ ;;
+ force-stop)
+ # First try to stop gracefully the program
+ $0 stop
+ if running; then
+ # If it's still running try to kill it more forcefully
+ log_daemon_msg "Stopping (force) $DESC" "$NAME"
+ force_stop
+ log_end_msg $?
+ fi
+ ;;
+ restart|force-reload)
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ stop_server
+ # Wait some sensible amount, some server need this
+ [ -n "$DIETIME" ] && sleep $DIETIME
+ start_server
+ running
+ log_end_msg $?
+ ;;
+ status)
+
+ log_daemon_msg "Checking status of $DESC" "$NAME"
+ if running ; then
+ log_progress_msg "running"
+ log_end_msg 0
+ else
+ log_progress_msg "apparently not running"
+ log_end_msg 1
+ exit 1
+ fi
+ ;;
+ # Use this if the daemon cannot reload
+ reload)
+ log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon"
+ log_warning_msg "cannot re-read the config file (use restart)."
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+controller/controller usr/sbin
--- /dev/null
+controller/controller.8
--- /dev/null
+#!/bin/sh
+# postinst script for openflow-controller
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /etc/openflow-controller
+ if ! test -e cacert.pem; then
+ ln -s /usr/share/openflow/pki/switchca/cacert.pem cacert.pem
+ fi
+ if ! test -e privkey.pem || ! test -e cert.pem; then
+ oldumask=$(umask)
+ umask 077
+ ofp-pki req+sign tmp controller >/dev/null
+ mv tmp-privkey.pem privkey.pem
+ mv tmp-cert.pem cert.pem
+ mv tmp-req.pem req.pem
+ chmod go+r cert.pem req.pem
+ umask $oldumask
+ fi
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
+
+
--- /dev/null
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+depmod -a
+
+#DEBHELPER#
+
+exit 0
+
+
--- /dev/null
+OpenFlow for Debian
+-------------------
+
+* How do I build this module the Debian way?
+
+ - Building with module-assistant:
+
+ $ module-assistant auto-install openflow
+ or
+ $ m-a a-i openflow
+
+ If kernel source or headers are in a non-standard directory, add
+ the option -k /path/to/kernel/source with the correct path.
+
+ - Building with make-kpkg
+
+ $ cd /usr/src/
+ $ tar jxvf openflow.tar.bz2
+ $ cd /usr/src/kernel-source-2.6.9
+ $ make-kpkg --added-modules=openflow modules
+
+ - Building without make-kpkg
+
+ $ cd /usr/src/
+ $ tar jxvf openflow.tar.bz2
+ $ cd modules/openflow
+ $ fakeroot debian/rules kdist_image
+
+ If you run this as root, fakeroot is not needed.
+
+ -- OpenFlow Team <openflow-dev@lists.stanford.edu>, Thu, 12 Jun 2008 16:42:38 -0700
--- /dev/null
+Upstream Authors:
+
+ The Board of Trustees of The Leland Stanford Junior University
+
+Copyright:
+
+ Copyright (C) 2008 The Board of Trustees of The Leland Stanford
+ Junior University
+
+License:
+
+ Files in the datapath/ and its sub-directories are covered under the GNU
+ General Public License Version 2.
+
+ On Debian systems, the complete text of the GNU General
+ Public License can be found in `/usr/share/common-licenses/GPL'.
--- /dev/null
+usr/src/modules/openflow-datapath/debian
--- /dev/null
+Alias /openflow/pki/ /usr/share/openflow/pki/
--- /dev/null
+etc/apache2/sites-available
--- /dev/null
+utilities/ofp-pki-cgi usr/lib/cgi-bin
--- /dev/null
+#!/bin/sh
+# postinst script for openflow
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+case "$1" in
+ configure)
+ # Create certificate authorities.
+ if test ! -d /usr/share/openflow/pki; then
+ ofp-pki init
+ fi
+
+ # Enable site under Apache.
+ a2ensite openflow-pki >/dev/null
+ if command -v invoke-rc.d >/dev/null 2>&1; then
+ invoke-rc.d apache2 force-reload || :
+ else
+ [ -x /etc/init.d/apache2 ] && /etc/init.d/apache2 force-reload || :
+ fi
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
+
+
--- /dev/null
+README.Debian for openflow-switch
+---------------------------------
+
+* The switch must be configured before it can be used. To configure
+ it interactively, run the ofp-switch-setup program. Alternatively,
+ edit /etc/default/openflow-switch by hand, then start the switch
+ manually with "/etc/init.d/openflow-switch start".
+
+* To use the Linux kernel-based switch implementation, you will need
+ to build and install the OpenFlow kernel module. To do so, install
+ the openflow-datapath-source package, then follow the instructions
+ given in /usr/share/doc/openflow-datapath-source/README.Debian
+
+* This package does not yet support the userspace switch
+ implementation.
--- /dev/null
+#!/bin/sh
+set -e
+. /usr/share/debconf/confmodule
+# Nothing more to do -- the user is responsible for running ofp-switch-setup.
--- /dev/null
+# This is a POSIX shell fragment -*- sh -*-
+
+# To configure the secure channel, fill in the following properly and
+# uncomment them. Afterward, the secure channel will come up
+# automatically at boot time. It can be started immediately with
+# /etc/init.d/openflow-switch start
+# Alternatively, use the ofp-switch-setup program to do everything
+# automatically.
+
+# NETDEVS: Which network devices should the OpenFlow switch include?
+#
+# List the network devices that should become part of the OpenFlow
+# switch, separated by spaces. At least two devices must be selected
+# for this machine to be a useful switch. Unselecting all network
+# devices will disable the OpenFlow switch entirely.
+#
+# The network devices that you select should not be configured with IP
+# or IPv6 addresses, even if the switch contacts the controller over
+# one of the selected network devices. This is because a running
+# OpenFlow switch takes over network devices at a low level: they
+# 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:
+#
+# * 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.
+#
+# * 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 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
+
+# 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:
+#
+# * For static configuration, specify the switch's IP address as a
+# string.
+#
+# * For dynamic configuration with DHCP (the most common case),
+# specify "dhcp". Configuration with DHCP will only work reliably
+# 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.
+SWITCH_IP=dhcp
+
+# CONTROLLER: Location of controller.
+# One of the following formats:
+# 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.
+#CONTROLLER="tcp:127.0.0.1"
+
+# PRIVKEY: Name of file containing switch's private key.
+# Required if SSL enabled.
+#PRIVKEY=/etc/openflow-switch/of0-privkey.pem
+
+# CERT: Name of file containing certificate for private key.
+# Required if SSL enabled.
+#CERT=/etc/openflow-switch/of0-cert.pem
+
+# CACERT: Name of file containing controller CA certificate.
+# Required if SSL enabled.
+#CACERT=/etc/openflow-switch/cacert.pem
+
+# Additional options to pass to secchan, e.g. "--fail=open"
+DAEMON_OPTS=""
--- /dev/null
+/etc/openflow-switch
+/usr/share/lintian/overrides
--- /dev/null
+#! /bin/sh
+#
+# /etc/init.d/openflow-switch
+#
+# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
+# Modified for Debian by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+# Further changes by Javier Fernandez-Sanguino <jfs@debian.org>
+# Modified for openflow-switch.
+#
+# Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl
+#
+### BEGIN INIT INFO
+# Provides: openflow-switch
+# Required-Start: $network $named $remote_fs $syslog
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: OpenFlow switch
+### END INIT INFO
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/secchan
+NAME=secchan
+DESC=secchan
+
+test -x $DAEMON || exit 0
+
+LOGDIR=/var/log/openflow
+PIDFILE=/var/run/$NAME.pid
+DHCLIENT_PIDFILE=/var/run/dhclient.of0.pid
+DODTIME=1 # Time to wait for the server to die, in seconds
+ # If this value is set too low you might not
+ # let some servers to die gracefully and
+ # 'restart' will not work
+
+# Include secchan defaults if available
+default=/etc/default/openflow-switch
+if [ -f $default ] ; then
+ . $default
+fi
+
+set -e
+
+running_pid()
+{
+ # Check if a given process pid's cmdline matches a given name
+ pid=$1
+ name=$2
+ [ -z "$pid" ] && return 1
+ [ ! -d /proc/$pid ] && return 1
+ cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
+ # Is this the expected child?
+ [ "$cmd" != "$name" ] && return 1
+ return 0
+}
+
+running()
+{
+# Check if the process is running looking at /proc
+# (works for all users)
+
+ # No pidfile, probably no daemon present
+ [ ! -f "$PIDFILE" ] && return 1
+ # Obtain the pid and check it against the binary name
+ pid=`cat $PIDFILE`
+ running_pid $pid $NAME || return 1
+ return 0
+}
+
+force_stop() {
+# Forcefully kill the process
+ [ ! -f "$PIDFILE" ] && return
+ if running ; then
+ kill -15 $pid
+ # Is it really dead?
+ [ -n "$DODTIME" ] && sleep "$DODTIME"s
+ if running ; then
+ kill -9 $pid
+ [ -n "$DODTIME" ] && sleep "$DODTIME"s
+ if running ; then
+ echo "Cannot kill $LABEL (pid=$pid)!"
+ exit 1
+ fi
+ fi
+ fi
+ rm -f $PIDFILE
+ return 0
+}
+
+must_succeed() {
+ echo -n "$1: "
+ shift
+ if "$@"; then
+ echo "success."
+ else
+ echo " ERROR."
+ exit 1
+ fi
+}
+
+check_op() {
+ echo -n "$1: "
+ shift
+ if "$@"; then
+ echo "success."
+ else
+ echo " ERROR."
+ fi
+}
+
+case "$1" in
+ start)
+ if test -z "$NETDEVS"; then
+ echo "$default: No network devices configured, switch disabled" >&2
+ 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
+ echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
+ exit 1
+ fi
+ case $CONTROLLER in
+ 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
+ ;;
+ *)
+ echo "$default: CONTROLLER must be in the form 'ssl:HOST[:PORT]' or 'tcp:HOST[:PORT]'" >&2
+ echo "Run ofp-switch-setup or edit /etc/default/openflow-switch to configure" >&2
+ exit 1
+ esac
+
+ echo -n "Loading openflow_mod: "
+ if modprobe openflow_mod; then
+ echo "success."
+ else
+ echo " ERROR."
+ echo "openflow_mod has probably not been built for this kernel."
+ if ! test -d /usr/share/doc/openflow-datapath-source; then
+ echo "Install the openflow-datapath-source package, then read"
+ echo "/usr/share/doc/openflow-datapath-source/README.Debian"
+ else
+ echo "For instructions, read"
+ echo "/usr/share/doc/openflow-datapath-source/README.Debian"
+ fi
+ exit 1
+ fi
+
+ must_succeed "Adding datapath" dpctl adddp nl:0
+ for netdev in $NETDEVS; do
+ must_succeed "Adding $netdev to datapath" dpctl addif nl:0 $netdev
+ done
+
+ if test "$IN_BAND" = yes; then
+ if test "$SWITCH_IP" = dhcp; then
+ must_succeed "Temporarily disabling of0" ifconfig of0 down
+ else
+ must_succeed "Configuring of0 as $SWITCH_IP" ifconfig of0 $SWITCH_IP
+ fi
+ else
+ must_succeed "Disabling of0" ifconfig of0 down
+ fi
+
+ echo -n "Starting $DESC: "
+ start-stop-daemon --start --quiet --pidfile $PIDFILE \
+ --exec $DAEMON -- nl:0 $CONTROLLER --detach --pidfile=$PIDFILE \
+ $DAEMON_OPTS $SSL_OPTS
+ if running; then
+ echo "$NAME."
+ else
+ echo " ERROR."
+ fi
+
+ if test "$IN_BAND" = yes && 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
+ if running; then
+ echo "dhclient."
+ else
+ echo " ERROR."
+ fi
+ fi
+ ;;
+ stop)
+ if test -e /var/run/dhclient.of0.pid; then
+ echo -n "Stopping dhclient on of0: "
+ start-stop-daemon --stop --quiet --oknodo \
+ --pidfile $DHCLIENT_PIDFILE --exec /sbin/dhclient
+ echo "dhclient."
+ fi
+
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE \
+ --exec $DAEMON
+ echo "$NAME."
+
+ for netdev in $NETDEVS; do
+ check_op "Removing $netdev from datapath" dpctl delif nl:0 $netdev
+ done
+ check_op "Deleting datapath" dpctl deldp nl:0
+ ;;
+ force-stop)
+ echo -n "Forcefully stopping $DESC: "
+ force_stop
+ if ! running; then
+ echo "$NAME."
+ else
+ echo " ERROR."
+ fi
+ ;;
+ reload)
+ ;;
+ force-reload)
+ start-stop-daemon --stop --test --quiet --pidfile \
+ $PIDFILE --exec $DAEMON \
+ && $0 restart \
+ || exit 0
+ ;;
+ restart)
+ $0 stop || true
+ $0 start
+ ;;
+ status)
+ echo -n "$LABEL is "
+ if running ; then
+ echo "running"
+ else
+ echo " not running."
+ exit 1
+ fi
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ echo "Usage: $N {start|stop|restart|force-reload|status|force-stop}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+switch/switch usr/sbin
+secchan/secchan usr/sbin
+utilities/dpctl usr/sbin
+debian/ofp-switch-setup usr/sbin
--- /dev/null
+/usr/share/modass/packages/default.sh /usr/share/modass/packages/openflow-datapath-source
--- /dev/null
+debian/ofp-switch-setup.8
+secchan/secchan.8
+switch/switch.8
+utilities/dpctl.8
--- /dev/null
+debconf-is-not-a-registry
--- /dev/null
+#!/bin/sh
+# postinst script for openflow-switch
+#
+# see: dh_installdeb(1)
+
+set -e
+
+. /usr/share/debconf/confmodule
+
+#DEBHELPER#
+
+exit 0
+
+
--- /dev/null
+Template: openflow-switch/netdevs
+Type: multiselect
+_Choices: ${choices}
+_Description: OpenFlow switch network devices:
+ Choose the network devices that should become part of the OpenFlow
+ switch. At least two devices must be selected for this machine to be
+ a useful switch. Unselecting all network devices will disable the
+ OpenFlow switch entirely.
+ .
+ The network devices that you select should not be configured with IP
+ or IPv6 addresses, even if the switch contacts the controller over
+ one of the selected network devices. This is because a running
+ OpenFlow switch takes over network devices at a low level: they
+ become part of the switch and cannot be used for other purposes.
+
+Template: openflow-switch/no-netdevs
+Type: error
+_Description: No network devices were selected.
+ No network devices were selected for inclusion in the OpenFlow switch.
+ The switch will be disabled.
+
+Template: openflow-switch/configured-netdevs
+Type: note
+_Description: Some Network Devices Have IP or IPv6 Addresses
+ The following network devices selected to be part of the OpenFlow switch
+ have IP or IPv6 addresses configured:
+ .
+ ${configured-netdevs}
+ .
+ This is usually a mistake, even if the switch contacts the controller over
+ one of the selected network devices. This is because a running
+ OpenFlow switch takes over network devices at a low level: they
+ become part of the switch and cannot be used for other purposes.
+ .
+ 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
+Type: select
+_Choices: in-band, out-of-band
+Default: in-band
+_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:
+ .
+ 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.
+ .
+ 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/switch-ip
+Type: string
+Default: dhcp
+_Description: Switch IP address:
+ 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.
+ .
+ For static configuration, specify the switch's IP address as a string.
+ .
+ For dynamic configuration with DHCP (the most common case), specify "dhcp".
+ Configuration with DHCP will only work reliably if the network topology
+ allows the switch to contact the DHCP server before it connects to the
+ OpenFlow controller.
+
+Template: openflow-switch/switch-ip-error
+Type: error
+_Description: The switch IP address is invalid.
+ The switch IP address must specified as "dhcp" or a valid IP address in
+ dotted-octet form (e.g. "1.2.3.4").
+
+Template: openflow-switch/controller-vconn
+Type: string
+_Description: Controller location:
+ 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
+ over SSL (recommended for security) or "tcp:HOST[:PORT]" to connect over
+ cleartext TCP.
+
+Template: openflow-switch/controller-vconn-error
+Type: error
+_Description: The controller location is invalid.
+ The controller location must be specifed as "ssl:HOST[:PORT]" to
+ connect to the controller over SSL (recommended for security) or
+ "tcp:HOST[:PORT]" to connect over cleartext TCP.
+
+Template: openflow-switch/pki-host
+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.
+ .
+ The setup process will connect to the OpenFlow PKI server over
+ HTTP, using the system's configured default HTTP proxy (if any).
+
+Template: openflow-switch/fetch-cacert-failed
+Type: error
+_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
+ proxy, also make sure that the HTTP proxy is available and that the
+ PKI server can be reached through it.
+
+Template: openflow-switch/verify-controller-ca
+Type: select
+_Choices: yes, no
+Default: yes
+_Description: Is ${fingerprint} the controller CA's fingerprint?
+ 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" if it matches, "no" if
+ there is a discrepancy.
+ .
+ If a man-in-the-middle attack is not a concern, there is no need to
+ verify the fingerprint. Simply answer "yes".
+
+Template: openflow-switch/send-cert-req
+Type: select
+_Choices: yes, no
+Default: yes
+_Description: Send certificate request to switch CA?
+ 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 OpenFlow PKI server, which is usually collocated with
+ the OpenFlow controller. A signing request can be sent to the PKI
+ server now.
+ .
+ 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 request more than once.
+ .
+ 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 request and signing will be necessary.
+
+Template: openflow-switch/send-cert-req-failed
+Type: error
+_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}.
+
+Template: openflow-switch/fetch-switch-cert
+Type: select
+_Choices: yes, no
+_Description: Fetch signed switch certificate from PKI server?
+ 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 OpenFlow PKI server, which is usually collocated with
+ the OpenFlow controller.
+ .
+ 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 been retrieved. Manual action may need to be
+ taken at the PKI server to approve the signing request.
+ .
+ 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 server, this is the correct choice.
+ .
+ Answer "no" to postpone switch configuration. The configuration
+ process must be restarted later, when the switch certificate request
+ has been signed.
+
+Template: openflow-switch/fetch-switch-cert-failed
+Type: error
+_Description: Signed switch certificate could not be retrieved.
+ The signed switch certificate could not be retrieved from the switch
+ CA: retrieval of ${url} failed, with the following status: "${error}".
+ .
+ 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 again.
+
+Template: openflow-switch/complete
+Type: note
+_Description: OpenFlow Switch Setup Finished
+ Setup of this OpenFlow switch is finished. Complete the setup procedure
+ to enable the switch.
--- /dev/null
+[type: gettext/rfc822deb] openflow-switch.templates
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+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"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: multiselect
+#. Choices
+#: ../openflow-switch.templates:1001
+msgid "${choices}"
+msgstr ""
+
+#. Type: multiselect
+#. Description
+#: ../openflow-switch.templates:1002
+msgid "OpenFlow switch network devices:"
+msgstr ""
+
+#. Type: multiselect
+#. Description
+#: ../openflow-switch.templates:1002
+msgid ""
+"Choose the network devices that should become part of the OpenFlow switch. "
+"At least two devices must be selected for this machine to be a useful "
+"switch. Unselecting all network devices will disable the OpenFlow switch "
+"entirely."
+msgstr ""
+
+#. Type: multiselect
+#. Description
+#: ../openflow-switch.templates:1002
+msgid ""
+"The network devices that you select should not be configured with IP or IPv6 "
+"addresses, even if the switch contacts the controller over one of the "
+"selected network devices. This is because a running OpenFlow switch takes "
+"over network devices at a low level: they become part of the switch and "
+"cannot be used for other purposes."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:2001
+msgid "No network devices were selected."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:2001
+msgid ""
+"No network devices were selected for inclusion in the OpenFlow switch. The "
+"switch will be disabled."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:3001
+msgid "Some Network Devices Have IP or IPv6 Addresses"
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:3001
+msgid ""
+"The following network devices selected to be part of the OpenFlow switch "
+"have IP or IPv6 addresses configured:"
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:3001
+msgid "${configured-netdevs}"
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:3001
+msgid ""
+"This is usually a mistake, even if the switch contacts the controller over "
+"one of the selected network devices. This is because a running OpenFlow "
+"switch takes over network devices at a low level: they become part of the "
+"switch and cannot be used for other purposes."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:3001
+msgid ""
+"If this is an unintentional mistake, move back and fix the selection, or de-"
+"configure the IP or IPv6 from these network devices."
+msgstr ""
+
+#. Type: select
+#. Choices
+#: ../openflow-switch.templates:4001
+msgid "in-band, out-of-band"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:4002
+msgid "Switch-to-controller access method:"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:4002
+msgid ""
+"The OpenFlow switch must be able to contact the OpenFlow controller over the "
+"network. It can do so in one of two ways:"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:4002
+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 "
+"devices selected as OpenFlow switch netdevs in the previous question. This "
+"is the most common case."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:4002
+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 "
+"configured on a network device other than one of those selected as an "
+"OpenFlow switch netdev in the previous question."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "Switch IP address:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:5001
+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 "
+"statically or dynamically."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:5001
+msgid "For static configuration, specify the switch's IP address as a string."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:5001
+msgid ""
+"For dynamic configuration with DHCP (the most common case), specify \"dhcp"
+"\". Configuration with DHCP will only work reliably if the network topology "
+"allows the switch to contact the DHCP server before it connects to the "
+"OpenFlow controller."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:6001
+msgid "The switch IP address is invalid."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:6001
+msgid ""
+"The switch IP address must specified as \"dhcp\" or a valid IP address in "
+"dotted-octet form (e.g. \"1.2.3.4\")."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:7001
+msgid "Controller location:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:7001
+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 "
+"over SSL (recommended for security) or \"tcp:HOST[:PORT]\" to connect over "
+"cleartext TCP."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:8001
+msgid "The controller location is invalid."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:8001
+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]\" "
+"to connect over cleartext TCP."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:9001
+msgid "OpenFlow PKI server host name:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:9001
+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."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../openflow-switch.templates:9001
+msgid ""
+"The setup process will connect to the OpenFlow PKI server over HTTP, using "
+"the system's configured default HTTP proxy (if any)."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:10001
+msgid "The switch CA certificate could not be retrieved."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:10001
+msgid "Retrieval of ${url} failed, with the following status: \"${error}\"."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:10001
+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 "
+"sure that the HTTP proxy is available and that the PKI server can be reached "
+"through it."
+msgstr ""
+
+#. Type: select
+#. Choices
+#. Type: select
+#. Choices
+#. Type: select
+#. Choices
+#: ../openflow-switch.templates:11001 ../openflow-switch.templates:12001
+#: ../openflow-switch.templates:14001
+msgid "yes, no"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:11002
+msgid "Is ${fingerprint} the controller CA's fingerprint?"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:11002
+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"
+"\" if it matches, \"no\" if there is a discrepancy."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:11002
+msgid ""
+"If a man-in-the-middle attack is not a concern, there is no need to verify "
+"the fingerprint. Simply answer \"yes\"."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:12002
+msgid "Send certificate request to switch CA?"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:12002
+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 "
+"OpenFlow PKI server, which is usually collocated with the OpenFlow "
+"controller. A signing request can be sent to the PKI server now."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:12002
+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 "
+"request more than once."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:12002
+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 "
+"request and signing will be necessary."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:13001
+msgid "The certificate request could not be sent."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:13001
+msgid "Posting to ${url} failed, with the following status: \"${error}\"."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:13001
+msgid ""
+"Ensure that the OpenFlow PKI server is correctly configured and available on "
+"${pki-host}."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:14002
+msgid "Fetch signed switch certificate from PKI server?"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:14002
+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 "
+"OpenFlow PKI server, which is usually collocated with the OpenFlow "
+"controller."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:14002
+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 "
+"been retrieved. Manual action may need to be taken at the PKI server to "
+"approve the signing request."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:14002
+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 "
+"server, this is the correct choice."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../openflow-switch.templates:14002
+msgid ""
+"Answer \"no\" to postpone switch configuration. The configuration process "
+"must be restarted later, when the switch certificate request has been signed."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:15001
+msgid "Signed switch certificate could not be retrieved."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:15001
+msgid ""
+"The signed switch certificate could not be retrieved from the switch CA: "
+"retrieval of ${url} failed, with the following status: \"${error}\"."
+msgstr ""
+
+#. Type: error
+#. Description
+#: ../openflow-switch.templates:15001
+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 again."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:16001
+msgid "OpenFlow Switch Setup Finished"
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../openflow-switch.templates:16001
+msgid ""
+"Setup of this OpenFlow switch is finished. Complete the setup procedure to "
+"enable the switch."
+msgstr ""
--- /dev/null
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+#
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+#
+# Modified to make a template file for a multi-binary package with separated
+# build-arch and build-indep targets by Bill Allombert 2001
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This has to be exported to make some magic below work.
+export DH_OPTIONS
+
+# prefix of the target package name
+PACKAGE=openflow-datapath-module
+# modifieable for experiments or debugging m-a
+MA_DIR ?= /usr/share/modass
+# load generic variable handling
+-include $(MA_DIR)/include/generic.make
+# load default rules
+-include $(MA_DIR)/include/common-rules.make
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ test -e configure || ./boot.sh
+ test -e Makefile || \
+ ./configure --prefix=/usr --localstatedir=/var --enable-ssl
+ touch configure-stamp
+
+#Architecture
+build: build-arch build-indep
+
+build-arch: build-arch-stamp
+build-arch-stamp: configure-stamp
+ $(MAKE)
+ touch $@
+
+build-indep: build-indep-stamp
+build-indep-stamp: configure-stamp
+ $(MAKE) dist distdir=openflow
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-arch-stamp build-indep-stamp configure-stamp
+ [ ! -f Makefile ] || $(MAKE) distclean
+ dh_clean
+ debconf-updatepo
+
+MAJOR=$(shell echo $(KVERS) | sed -e 's/\(...\).*/\1/')
+ifeq ($(MAJOR),2.6)
+KO=k
+l2x=l26
+dpdir=datapath/linux-2.6
+else
+KO=
+l2x=l24
+dpdir=datapath/linux-2.4
+endif
+
+kdist_clean:
+ dh_clean
+ make KERNELDIR=$(KSRC) KVERREL=$(KVERS) clean
+
+kdist_config: prep-deb-files
+
+binary-modules: DSTDIR = $(CURDIR)/debian/$(PKGNAME)/lib/modules/$(KVERS)
+binary-modules: prep-deb-files
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ tar xzf openflow.tar.gz
+ cd openflow && ./configure --with-$(l2x)=$(KSRC)
+ cd openflow && $(MAKE) -C $(dpdir)
+ install -d -m755 $(DSTDIR)
+ install -m644 openflow/$(dpdir)/*_mod.$(KO)o $(DSTDIR)/
+ dh_installdocs
+ dh_installchangelogs
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_gencontrol -- -v$(VERSION)
+ dh_md5sums
+ dh_builddeb --destdir=$(DEB_DESTDIR)
+
+install: install-indep install-arch
+install-indep: MODDIR = $(CURDIR)/debian/openflow-datapath-source/usr/src/modules/openflow-datapath
+install-indep: build-indep
+ dh_testdir
+ dh_testroot
+ dh_clean -k -i
+ dh_installdirs -i
+ cp openflow.tar.gz $(MODDIR)
+ cd debian; cp changelog control compat *.modules.in rules $(MODDIR)/debian
+ cd debian/openflow-datapath-source/usr/src && tar -c modules | bzip2 -9 > openflow-datapath.tar.bz2 && rm -rf modules
+ install -m644 debian/openflow-pki.apache2 debian/openflow-pki/etc/apache2/sites-available/openflow-pki
+ dh_install -i
+
+install-arch: build-arch
+ dh_testdir
+ dh_testroot
+ dh_clean -k -s
+ dh_installdirs -s
+ $(MAKE) DESTDIR=$(CURDIR)/debian/openflow install
+ cp debian/openflow-switch.overrides debian/openflow-switch/usr/share/lintian/overrides/openflow-switch
+ dh_install -s
+
+# Must not depend on anything. This is to be called by
+# binary-arch/binary-indep
+# in another 'make' thread.
+binary-common:
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+ dh_installdebconf
+# dh_installlogrotate
+ dh_installinit
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_perl
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+binary-indep: install-indep
+ $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
+binary-arch: install-arch
+ $(MAKE) -f debian/rules DH_OPTIONS=-s binary-common
+
+binary: binary-arch binary-indep
+.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch configure
/Makefile
/Makefile.in
/dpctl
+/ofp-pki
+/ofp-pki-cgi
+/ofp-pki.8
/vlogconf
include ../Make.vars
bin_PROGRAMS = vlogconf dpctl
-dist_man_MANS = vlogconf.8 dpctl.8 ofp-pki.8
+bin_SCRIPTS = ofp-pki
+noinst_SCRIPTS = ofp-pki-cgi
+
+EXTRA_DIST = ofp-pki.in ofp-pki-cgi.in ofp-pki.8.in
+DISTCLEANFILES = ofp-pki ofp-pki-cgi ofp-pki.8
+
+dist_man_MANS = vlogconf.8 dpctl.8
+man_MANS = ofp-pki.8
dpctl_SOURCES = dpctl.c
dpctl_LDADD = ../lib/libopenflow.la
vlogconf_SOURCES = vlogconf.c
vlogconf_LDADD = ../lib/libopenflow.la
+
+pkidir = $(pkgdatadir)/pki
+
+ofp-pki: ofp-pki.in Makefile
+ $(do_subst) < $(srcdir)/ofp-pki.in | $(ro_script) > ofp-pki
+ chmod +x ofp-pki
+ofp-pki-cgi: ofp-pki-cgi.in Makefile
+ $(do_subst) < $(srcdir)/ofp-pki-cgi.in | $(ro_script) > ofp-pki-cgi
+ chmod +x ofp-pki-cgi
+ofp-pki.8: ofp-pki.8.in Makefile
+ ($(do_subst) && $(ro_man)) < $(srcdir)/ofp-pki.8.in > ofp-pki.8
+++ /dev/null
-#! /bin/sh -e
-
-DIR=pki
-command=
-arg1=
-arg2=
-prev=
-force=no
-batch=no
-log=ofp-pki.log
-for option; do
- # This option-parsing mechanism borrowed from a Autoconf-generated
- # configure script under the following license:
-
- # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
- # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
- # This configure script is free software; the Free Software Foundation
- # gives unlimited permission to copy, distribute and modify it.
-
- # If the previous option needs an argument, assign it.
- if test -n "$prev"; then
- eval $prev=\$option
- prev=
- continue
- fi
- case $option in
- *=*) optarg=`expr "X$option" : '[^=]*=\(.*\)'` ;;
- *) optarg=yes ;;
- esac
-
- case $dashdash$option in
- --)
- dashdash=yes ;;
- -h|--help)
- cat <<EOF
-ofp-pki, for managing a simple OpenFlow public key infrastructure
-usage: $0 [OPTION...] COMMAND [ARG...]
-where the valid commands and their arguments are:
- new-pki Create a new PKI
- req NAME Create new private key and certificate request
- named NAME-privkey.pem and NAME-req.pem, resp.
- TYPE is a certificate type: 'switch' or 'controller'
- sign NAME TYPE Sign switch certificate request NAME-req.pem,
- producing certificate NAME-cert.pem
- TYPE is a certificate type: 'switch' or 'controller'
- req+sign NAME TYPE Combine the above two steps, producing all three files.
- verify NAME TYPE Checks that NAME-cert.pem is a valid TYPE certificate
- TYPE is a certificate type: 'switch' or 'controller'
-The valid OPTIONS are:
- -d, --dir=DIR Directory where the PKI is located (default: pki)
- -f, --force Continue even if file or directory already exists
- -b, --batch Skip fingerprint verification
- -l, --log=FILE Log openssl output to FILE (default: ofp-log.log)
- -h, --help Print this usage message.
-EOF
- exit 0
- ;;
- --d*=*)
- DIR=$optarg
- ;;
- --d*|-d)
- prev=DIR
- ;;
- --force|-f)
- force=yes
- ;;
- --batch|-b)
- batch=yes
- ;;
- -*)
- echo "unrecognized option $option"
- exit 1
- ;;
- *)
- if test -z "$command"; then
- command=$option
- elif test -z "$arg1"; then
- arg1=$option
- elif test -z "$arg2"; then
- arg2=$option
- else
- echo "only two arguments may be specified"
- exit 1
- fi
- ;;
- esac
- shift
-done
-if test -n "$prev"; then
- option=--`echo $prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $option" >&2
- { (exit 1); exit 1; }; }
-fi
-if test -z "$command"; then
- echo "$0: missing command name; use --help for help"
- exit 1
-fi
-exec 3>>$log
-
-if test "$command" = "new-pki"; then
- if test -e "$DIR" && test "$force" != "yes"; then
- echo "$0: $DIR already exists"
- exit 1
- fi
-
- if test ! -d "$DIR"; then
- mkdir "$DIR"
- fi
- cd "$DIR"
-
- if test ! -e dsaparam.pem; then
- echo "Generating DSA parameters, please wait..."
- openssl dsaparam -out dsaparam.pem 2048 1>&3 2>&3
- fi
-
- # Create the request configuration.
- if test ! -e req.cnf; then
- cat > req.cnf <<EOF
-[ req ]
-prompt = no
-distinguished_name = req_distinguished_name
-
-[ req_distinguished_name ]
-C = US
-ST = CA
-L = Palo Alto
-O = OpenFlow
-OU = OpenFlow certifier
-CN = OpenFlow certificate
-EOF
- fi
-
- # Create the CAs.
- for ca in controllerca switchca; do
- echo "Creating $ca..."
- oldpwd=$PWD
- mkdir -p $ca
- cd $ca
-
- mkdir -p certs crl newcerts private
- touch index.txt
- test -e crlnumber || echo 01 > crlnumber
- test -e serial || echo 01 > serial
-
- # Put DSA parameters in directory.
- if test ! -e dsaparam.pem; then
- cp ../dsaparam.pem .
- fi
-
- # Write CA configuration file.
- if test ! -e ca.cnf; then
- cat > ca.cnf <<'EOF'
-[ req ]
-prompt = no
-distinguished_name = req_distinguished_name
-
-[ req_distinguished_name ]
-C = US
-ST = CA
-L = Palo Alto
-O = OpenFlow
-OU = OpenFlow
-CN = OpenFlow
-
-[ ca ]
-default_ca = the_ca
-
-[ the_ca ]
-dir = . # top dir
-database = $dir/index.txt # index file.
-new_certs_dir = $dir/newcerts # new certs dir
-certificate = $dir/cacert.pem # The CA cert
-serial = $dir/serial # serial no file
-private_key = $dir/private/cakey.pem# CA private key
-RANDFILE = $dir/private/.rand # random number file
-default_days = 365 # how long to certify for
-default_crl_days= 30 # how long before next CRL
-default_md = md5 # md to use
-policy = policy # default policy
-email_in_dn = no # Don't add the email into cert DN
-name_opt = ca_default # Subject name display option
-cert_opt = ca_default # Certificate display option
-copy_extensions = none # Don't copy extensions from request
-
-# For the CA policy
-[ policy ]
-countryName = optional
-stateOrProvinceName = optional
-organizationName = match
-organizationalUnitName = optional
-commonName = supplied
-emailAddress = optional
-EOF
- fi
-
- # Create certificate authority.
- openssl req -config ca.cnf -nodes \
- -newkey dsa:dsaparam.pem -keyout private/cakey.pem -out careq.pem \
- 1>&3 2>&3
- openssl ca -config ca.cnf -create_serial -out cacert.pem \
- -days 1095 -batch -keyfile private/cakey.pem -selfsign \
- -infiles careq.pem 1>&3 2>&3
-
- cd "$oldpwd"
- done
- exit 0
-fi
-
-one_arg() {
- if test -z "$arg1" || test -n "$arg2"; then
- echo "$0: $command must have exactly one argument; use --help for help"
- exit 1
- fi
-}
-
-two_args() {
- if test -z "$arg1" || test -z "$arg2"; then
- echo "$0: $command must have exactly two arguments; use --help for help"
- exit 1
- fi
-}
-
-must_not_exist() {
- if test -e "$1" && test "$force" != "yes"; then
- echo "$0: $1 already exists and --force not supplied"
- exit 1
- fi
-}
-
-fingerprint() {
- printf "$1-req.pem fingerprint is "
- sha1sum "$1-req.pem" | awk '{print $1}'
-}
-
-check_type() {
- if test "$1" != switch && test "$1" != controller; then
- echo "$0: type argument must be 'switch' or 'controller'"
- exit 1
- fi
-}
-
-must_exist() {
- if test ! -e "$1"; then
- echo "$0: $1 does not exist"
- exit 1
- fi
-}
-
-DIR_must_exist() {
- if test ! -e "$DIR"; then
- echo "$0: $DIR does not exist (need to use --dir or new-pki?)"
- exit 1
- elif test ! -d "$DIR"; then
- echo "$0: $DIR is not a directory"
- exit 1
- fi
-}
-
-make_request() {
- must_not_exist "$arg1-privkey.pem"
- must_not_exist "$arg1-req.pem"
- DIR_must_exist
- openssl req -config "$DIR/req.cnf" -text -nodes \
- -newkey "dsa:$DIR/dsaparam.pem" -keyout "$1-privkey.pem" \
- -out "$1-req.pem" 1>&3 2>&3
-}
-
-sign_request() {
- must_exist "$1-req.pem"
- must_not_exist "$1-cert.pem"
- check_type "$2"
- DIR_must_exist
- (cd "$DIR/$2ca" && openssl ca -config ca.cnf -batch -in /dev/stdin) \
- < "$1-req.pem" > "$1-cert.pem.tmp" 2>&3
- mv "$1-cert.pem.tmp" "$1-cert.pem"
-}
-
-if test "$command" = req; then
- one_arg
- make_request "$arg1"
- fingerprint "$arg1"
-elif test "$command" = sign; then
- two_args
- fingerprint "$arg1"
- if test $batch != yes; then
- echo "Does fingerprint match? (yes/no)"
- read answer
- if test "$answer" != yes; then
- echo "Match failure, aborting"
- exit 1
- fi
- fi
- sign_request "$arg1" "$arg2"
-elif test "$command" = req+sign; then
- two_args
- make_request "$arg1"
- sign_request "$arg1" "$arg2"
- fingerprint "$arg1"
-elif test "$command" = verify; then
- two_args
- must_exist "$arg1-cert.pem"
- check_type "$arg2"
- DIR_must_exist
- openssl verify -CAfile "$DIR/${arg2}ca/cacert.pem" "$arg1-cert.pem"
-else
- echo "$0: $command command unknown; use --help for help"
- exit 1
-fi
--- /dev/null
+#! @PERL@
+
+use CGI;
+use Digest::SHA1;
+use Fcntl;
+
+$CGI::POST_MAX = 65536; # Limit POSTs to 64 kB.
+
+use strict;
+use warnings;
+
+my $pkidir = '@pkidir@';
+my $q = new CGI;
+
+die unless $q->request_method() eq 'POST';
+
+my $type = $q->param('type');
+die unless defined $type;
+die unless $type eq 'switch' or $type eq 'controller';
+
+my $req = $q->param('req');
+die unless defined $req;
+die unless $req =~ /^-----BEGIN CERTIFICATE REQUEST-----$/m;
+die unless $req =~ /^-----END CERTIFICATE REQUEST-----$/m;
+
+my $digest = Digest::SHA1::sha1_hex($req);
+my $incoming = "$pkidir/${type}ca/incoming";
+my $dst = "$incoming/$digest-req.pem";
+
+sysopen(REQUEST, "$dst.tmp", O_RDWR | O_CREAT | O_EXCL, 0600)
+ or die "sysopen $dst.tmp: $!";
+print REQUEST $req;
+close(REQUEST) or die "close $dst.tmp: $!";
+
+rename("$dst.tmp", $dst) or die "rename $dst.tmp to $dst: $!";
+
+print $q->header('text/html', '204 No response');
+
+# Local Variables:
+# mode: perl
+# End:
+++ /dev/null
-.TH ofp-pki 8 "May 2008" "OpenFlow" "OpenFlow Manual"
-
-.SH NAME
-ofp\-pki \- OpenFlow public key infrastructure management utility
-
-.SH SYNOPSIS
-\fBofp\-pki\fR [\fIOPTIONS\fR] \fICOMMAND\fR [\fIARGS\fR]
-.sp
-Commands with their arguments:
-.br
-\fBofp\-pki\fR \fBnew-pki\fR
-.br
-\fBofp\-pki\fR \fBreq\fR \fINAME\fR
-.br
-\fBofp\-pki\fR \fBsign\fR \fINAME\fR \fITYPE\fR
-.br
-\fBofp\-pki\fR \fBreq+sign\fR \fINAME\fR \fITYPE\fR
-.br
-\fBofp\-pki\fR \fBverify\fR \fINAME\fR \fITYPE\fR
-.sp
-The available options are:
-.br
-[\fB-d\fR \fIDIR\fR | \fB--dir=\fR\fIDIR\fR] [\fB-f\fR | \fB--force\fR] [\fB-b\fR | \fB--batch\fR] [\fB-l\fR \fIFILE\fR | \fB--log=\fIFILE\fR] [\fB-h\fR | \fB--help\fR]
-
-.SH DESCRIPTION
-The \fBofp-pki\fR program sets up and manages a public key
-infrastructure for use with OpenFlow. It is intended to be a simple
-interface for organizations that do not have an established public key
-infrastructure. Other PKI tools can substitute for or supplement the
-use of \fBofp-pki\fR.
-
-\fBofp-pki\fR uses \fBopenssl\fR(1) for certificate management and key
-generation.
-
-The commands supported by \fBofp-pki\fR are:
-
-.TP
-\fBnew-pki\fR
-Creates a new PKI directory (by default named \fBpki\fR) and populates
-it with a pair of certificate authorities for controllers and
-switches.
-
-This command should ideally be run on a high-security machine separate
-from any OpenFlow controller or switch, called the CA machine. The
-files \fBpki/controllerca/cacert.pem\fR and
-\fBpki/switchca/cacert.pem\fR that it produces will need to be copied
-over to the OpenFlow switches and controllers, respectively. Their
-contents may safely be made public.
-
-Other files generated by \fBnew-pki\fR may remain on the CA machine.
-The files \fBpki/controllerca/private/cakey.pem\fR and
-\fBpki/switchca/private/cakey.pem\fR have particularly sensitive
-contents that should not be exposed.
-
-.TP
-\fBreq\fR \fINAME\fR
-Generates a new private key named \fINAME\fR\fB-privkey.pem\fR and
-corresponding certificate request named \fINAME\fR\fB-req.pem\fR.
-The private key can be intended for use by a switch or a controller.
-
-This command should ideally be run on the switch or controller that
-will use the private key to identify itself. The file
-\fINAME\fR\fB-req.pem\fR must be copied to the CA machine for signing
-with the \fBsign\fR command (below).
-
-This command will output a fingerprint to stdout as its final step.
-Write down the fingerprint and take it to the CA machine before
-continuing with the \fBsign\fR step.
-
-\fINAME\fR\fB-privkey.pem\fR has sensitive contents that should not be
-exposed. \fINAME\fR\fB-req.pem\fR may be safely made public.
-
-.TP
-\fBsign\fR \fINAME\fR \fITYPE\fR
-Signs the certificate request named \fINAME\fR\fB-req.pem\fR that was
-produced in the previous step, producing a certificate named
-\fINAME\fR\fB-cert.pem\fR. \fITYPE\fR, which must be \fBswitch\fR or
-\fBcontroller\fR, indicates the use for which the key is being
-certified.
-
-This command must be run on the CA machine.
-
-The command will output a fingerprint to stdout and request that you
-verify that it is the same fingerprint output by the \fBreq\fR
-command. This ensures that the request being signed is the same one
-produced by \fBreq\fR.
-
-The file \fINAME\fR\fB-cert.pem\fR will need to be copied back to the
-switch or controller for which it is intended. Its contents may
-safely be made public.
-
-.TP
-\fBreq+sign\fR \fINAME\fR \fITYPE\fR
-Combines the \fBreq\fR and \fBsign\fR commands into a single step,
-outputting all the files produced by each. The
-\fINAME\fR\fB-privkey.pem\fR and \fINAME\fR\fB-cert.pem\fR files must
-be copied securely to the switch or controller.
-\fINAME\fR\fB-privkey.pem\fR has sensitive contents and must not be
-exposed in transit. Afterward, it should be deleted from the CA
-machine.
-
-This combined method is, theoretically, less secure than the
-individual steps performed separately on two different machines,
-because there is additional potential for exposure of the private
-key. However, it is also more convenient.
-
-.TP
-\fBverify\fR \fINAME\fR \fITYPE\fR
-Verifies that \fINAME\fR\fB-cert.pem\fR is a valid certificate for the
-given \fITYPE\fR of use (either \fBswitch\fR or \fBcontroller\fR). If
-the certificate is valid for this use, it prints the message
-``\fINAME\fR\fB-cert.pem\fR: OK''; otherwise, it prints an error
-message.
-
-.SH OPTIONS
-.TP
-[\fB-d\fR \fIDIR\fR | \fB--dir=\fR\fIDIR\fR]
-Specifies the location of the PKI hierarchy to be used or created by
-the command (default: \fBpki\fR under the current directory). The
-\fBreq\fR command does not need access to a PKI hierarchy.
-
-.TP
-[\fB-f\fR | \fB--force\fR]
-By default, \fBofp-pki\fR will not overwrite existing files or
-directories. This option overrides this behavior.
-
-.TP
-[\fB-b\fR | \fB--batch\fR]
-Suppresses the interactive verification of fingerprints that the
-\fBsign\fR command by default requires.
-
-.TP
-[\fB-l\fR \fIFILE\fR | \fB--log=\fIFILE\fR]
-Sets the log file to \fIFILE\fR (default: ofp-pki.log).
-
-.TP
-[\fB-h\fR | \fB--help\fR]
-Prints a help usage message and exits.
-
-.SH "SEE ALSO"
-
-.BR dpctl (8),
-.BR switch (8),
-.BR secchan (8),
-.BR controller (8)
--- /dev/null
+#! /bin/sh -e
+
+pkidir='@pkidir@'
+command=
+prev=
+force=no
+batch=no
+log=ofp-pki.log
+for option; do
+ # This option-parsing mechanism borrowed from a Autoconf-generated
+ # configure script under the following license:
+
+ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ # This configure script is free software; the Free Software Foundation
+ # gives unlimited permission to copy, distribute and modify it.
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval $prev=\$option
+ prev=
+ continue
+ fi
+ case $option in
+ *=*) optarg=`expr "X$option" : '[^=]*=\(.*\)'` ;;
+ *) optarg=yes ;;
+ esac
+
+ case $dashdash$option in
+ --)
+ dashdash=yes ;;
+ -h|--help)
+ cat <<EOF
+ofp-pki, for managing a simple OpenFlow public key infrastructure
+usage: $0 [OPTION...] COMMAND [ARG...]
+
+The valid stand-alone commands and their arguments are:
+ init Initialize the PKI
+ req NAME Create new private key and certificate request
+ named NAME-privkey.pem and NAME-req.pem, resp.
+ sign NAME [TYPE] Sign switch certificate request NAME-req.pem,
+ producing certificate NAME-cert.pem
+ req+sign NAME [TYPE] Combine the above two steps, producing all three files.
+ verify NAME [TYPE] Checks that NAME-cert.pem is a valid TYPE certificate
+ fingerprint FILE Prints the fingerprint for FILE
+
+The following additional commands manage an online PKI:
+ ls [PREFIX] [TYPE] Lists incoming requests of the given TYPE, optionally
+ limited to those whose fingerprint begins with PREFIX
+ flush [TYPE] Rejects all incoming requests of the given TYPE
+ reject PREFIX [TYPE] Rejects the incoming request(s) whose fingerprint begins
+ with PREFIX and has the given TYPE
+ approve PREFIX [TYPE] Approves the incoming request whose fingerprint begins
+ with PREFIX and has the given TYPE
+ expire [AGE] Rejects all incoming requests older than AGE, in
+ one of the forms Ns, Nmin, Nh, Nday (default: 1day)
+ prompt [TYPE] Interactively prompts to accept or reject each incoming
+ request of the given TYPE
+
+Each TYPE above is a certificate type: 'switch' (default) or 'controller'.
+
+The valid OPTIONS are:
+ -d, --dir=DIR Directory where the PKI is located
+ (default: $pkidir)
+ -f, --force Continue even if file or directory already exists
+ -b, --batch Skip fingerprint verification
+ -l, --log=FILE Log openssl output to FILE (default: ofp-log.log)
+ -h, --help Print this usage message.
+EOF
+ exit 0
+ ;;
+ --d*=*)
+ pkidir=$optarg
+ ;;
+ --d*|-d)
+ prev=pkidir
+ ;;
+ --l*=*)
+ log=$optarg
+ ;;
+ --l*|-l)
+ prev=log
+ ;;
+ --force|-f)
+ force=yes
+ ;;
+ --batch|-b)
+ batch=yes
+ ;;
+ -*)
+ echo "unrecognized option $option" >&2
+ exit 1
+ ;;
+ *)
+ if test -z "$command"; then
+ command=$option
+ elif test -z "${arg1+set}"; then
+ arg1=$option
+ elif test -z "${arg2+set}"; then
+ arg2=$option
+ else
+ echo "$option: only two arguments may be specified" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+done
+if test -n "$prev"; then
+ option=--`echo $prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $option" >&2
+ { (exit 1); exit 1; }; }
+fi
+if test -z "$command"; then
+ echo "$0: missing command name; use --help for help" >&2
+ exit 1
+fi
+
+if test "$command" = "init"; then
+ if test -e "$pkidir" && test "$force" != "yes"; then
+ echo "$0: $pkidir already exists" >&2
+ exit 1
+ fi
+
+ if test ! -d "$pkidir"; then
+ mkdir -p "$pkidir"
+ fi
+ cd "$pkidir"
+ exec 3>>$log
+
+ if test ! -e dsaparam.pem; then
+ echo "Generating DSA parameters, please wait..." >&2
+ openssl dsaparam -out dsaparam.pem 2048 1>&3 2>&3
+ fi
+
+ # Create the request configuration.
+ if test ! -e req.cnf; then
+ cat > req.cnf <<EOF
+[ req ]
+prompt = no
+distinguished_name = req_distinguished_name
+
+[ req_distinguished_name ]
+C = US
+ST = CA
+L = Palo Alto
+O = OpenFlow
+OU = OpenFlow certifier
+CN = OpenFlow certificate
+EOF
+ fi
+
+ # Create the CAs.
+ for ca in controllerca switchca; do
+ echo "Creating $ca..." >&2
+ oldpwd=$PWD
+ mkdir -p $ca
+ cd $ca
+
+ mkdir -p certs crl newcerts
+ mkdir -p -m 0700 private
+ mkdir -p -m 0733 incoming
+ touch index.txt
+ test -e crlnumber || echo 01 > crlnumber
+ test -e serial || echo 01 > serial
+
+ # Put DSA parameters in directory.
+ if test ! -e dsaparam.pem; then
+ cp ../dsaparam.pem .
+ fi
+
+ # Write CA configuration file.
+ if test ! -e ca.cnf; then
+ cat > ca.cnf <<'EOF'
+[ req ]
+prompt = no
+distinguished_name = req_distinguished_name
+
+[ req_distinguished_name ]
+C = US
+ST = CA
+L = Palo Alto
+O = OpenFlow
+OU = OpenFlow
+CN = OpenFlow
+
+[ ca ]
+default_ca = the_ca
+
+[ the_ca ]
+dir = . # top dir
+database = $dir/index.txt # index file.
+new_certs_dir = $dir/newcerts # new certs dir
+certificate = $dir/cacert.pem # The CA cert
+serial = $dir/serial # serial no file
+private_key = $dir/private/cakey.pem# CA private key
+RANDFILE = $dir/private/.rand # random number file
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = md5 # md to use
+policy = policy # default policy
+email_in_dn = no # Don't add the email into cert DN
+name_opt = ca_default # Subject name display option
+cert_opt = ca_default # Certificate display option
+copy_extensions = none # Don't copy extensions from request
+
+# For the CA policy
+[ policy ]
+countryName = optional
+stateOrProvinceName = optional
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+EOF
+ fi
+
+ # Create certificate authority.
+ openssl req -config ca.cnf -nodes \
+ -newkey dsa:dsaparam.pem -keyout private/cakey.pem -out careq.pem \
+ 1>&3 2>&3
+ openssl ca -config ca.cnf -create_serial -out cacert.pem \
+ -days 1095 -batch -keyfile private/cakey.pem -selfsign \
+ -infiles careq.pem 1>&3 2>&3
+ chmod 0700 private/cakey.pem
+
+ cd "$oldpwd"
+ done
+ exit 0
+fi
+
+one_arg() {
+ if test -z "$arg1" || test -n "$arg2"; then
+ echo "$0: $command must have exactly one argument; use --help for help" >&2
+ exit 1
+ fi
+}
+
+zero_or_one_args() {
+ if test -n "$arg2"; then
+ echo "$0: $command must have zero or one arguments; use --help for help" >&2
+ exit 1
+ fi
+}
+
+one_or_two_args() {
+ if test -z "$arg1"; then
+ echo "$0: $command must have one or two arguments; use --help for help" >&2
+ exit 1
+ fi
+}
+
+must_not_exist() {
+ if test -e "$1" && test "$force" != "yes"; then
+ echo "$0: $1 already exists and --force not supplied" >&2
+ exit 1
+ fi
+}
+
+resolve_prefix() {
+ test -n "$type" || exit 123 # Forgot to call check_type?
+
+ case $1 in
+ ????*)
+ ;;
+ *)
+ echo "Prefix $arg1 is too short (less than 4 hex digits)"
+ exit 0
+ ;;
+ esac
+
+ fingerprint=$(cd "$pkidir/${type}ca/incoming" && echo "$1"*-req.pem
+ | sed 's/-req\.pem$//')
+ case $fingerprint in
+ "${1}*")
+ echo "No certificate requests matching $1"
+ exit 1
+ ;;
+ *" "*)
+ echo "$1 matches more than one certificate request:"
+ echo $fingerprint | sed 's/ /\
+/g'
+ exit 1
+ ;;
+ *)
+ # Nothing to do.
+ ;;
+ esac
+ req="$pkidir/${type}ca/incoming/$fingerprint-req.pem"
+ cert="$pkidir/${type}ca/certs/$fingerprint-cert.pem"
+}
+
+make_tmpdir() {
+ TMP=/tmp/ofp-pki.tmp$$
+ rm -rf $TMP
+ trap "rm -rf $TMP" 0
+ mkdir -m 0700 $TMP
+}
+
+fingerprint() {
+ local file=$1
+ local name=${1-$2}
+ local date=$(date -r $file)
+ local fingerprint
+ if grep -q -e '-BEGIN CERTIFICATE-' "$file"; then
+ fingerprint=$(openssl x509 -noout -in "$file" -fingerprint |
+ sed 's/SHA1 Fingerprint=//' | tr -d ':')
+ else
+ fingerprint=$(sha1sum "$file" | awk '{print $1}')
+ fi
+ printf "$name\\t$date\\n"
+ case $file in
+ $fingerprint*)
+ printf "\\t(correct fingerprint in filename)\\n"
+ ;;
+ *)
+ printf "\\tfingerprint $fingerprint\\n"
+ ;;
+ esac
+}
+
+verify_fingerprint() {
+ fingerprint "$@"
+ if test $batch != yes; then
+ echo "Does fingerprint match? (yes/no)"
+ read answer
+ if test "$answer" != yes; then
+ echo "Match failure, aborting" >&2
+ exit 1
+ fi
+ fi
+}
+
+check_type() {
+ if test x = x"$1"; then
+ type=switch
+ elif test "$1" = switch || test "$1" = controller; then
+ type=$1
+ else
+ echo "$0: type argument must be 'switch' or 'controller'" >&2
+ exit 1
+ fi
+}
+
+parse_age() {
+ number=$(echo $1 | sed 's/^\([0-9]\+\)\([[:alpha:]]\+\)/\1/')
+ unit=$(echo $1 | sed 's/^\([0-9]\+\)\([[:alpha:]]\+\)/\2/')
+ case $unit in
+ s)
+ factor=1
+ ;;
+ min)
+ factor=60
+ ;;
+ h)
+ factor=3600
+ ;;
+ day)
+ factor=86400
+ ;;
+ *)
+ echo "$1: age not in the form Ns, Nmin, Nh, Nday (e.g. 1day)" >&2
+ exit 1
+ ;;
+ esac
+ echo $(($number * $factor))
+}
+
+must_exist() {
+ if test ! -e "$1"; then
+ echo "$0: $1 does not exist" >&2
+ exit 1
+ fi
+}
+
+pkidir_must_exist() {
+ if test ! -e "$pkidir"; then
+ echo "$0: $pkidir does not exist (need to run 'init' or use '--dir'?)" >&2
+ exit 1
+ elif test ! -d "$pkidir"; then
+ echo "$0: $pkidir is not a directory" >&2
+ exit 1
+ fi
+}
+
+make_request() {
+ must_not_exist "$arg1-privkey.pem"
+ must_not_exist "$arg1-req.pem"
+ pkidir_must_exist
+ openssl req -config "$pkidir/req.cnf" -text -nodes \
+ -newkey "dsa:$pkidir/dsaparam.pem" -keyout "$1-privkey.pem" \
+ -out "$1-req.pem" 1>&3 2>&3
+}
+
+sign_request() {
+ must_exist "$1"
+ must_not_exist "$2"
+ pkidir_must_exist
+
+ (cd "$pkidir/${type}ca" &&
+ openssl ca -config ca.cnf -batch -in /dev/stdin) \
+ < "$1" > "$2.tmp$$" 2>&3
+ mv "$2.tmp$$" "$2"
+}
+
+glob() {
+ local files=$(echo $1)
+ if test "$files" != "$1"; then
+ echo "$files"
+ fi
+}
+
+case $log in
+ /*)
+ exec 3>>$log || true
+ ;;
+ *)
+ exec 3>>$pkidir/$log || true
+ ;;
+esac
+
+if test "$command" = req; then
+ one_arg
+
+ make_request "$arg1"
+ fingerprint "$arg1-req.pem"
+elif test "$command" = sign; then
+ one_or_two_args
+ check_type "$arg2"
+ verify_fingerprint "$arg1-req.pem"
+
+ sign_request "$arg1-req.pem" "$arg2-cert.pem"
+elif test "$command" = req+sign; then
+ one_or_two_args
+ check_type "$arg2"
+
+ make_request "$arg1"
+ sign_request "$arg1-req.pem" "$arg1-cert.pem"
+ fingerprint "$arg1-req.pem"
+elif test "$command" = verify; then
+ one_or_two_args
+ must_exist "$arg1-cert.pem"
+ check_type "$arg2"
+
+ pkidir_must_exist
+ openssl verify -CAfile "$pkidir/${type}ca/cacert.pem" "$arg1-cert.pem"
+elif test "$command" = fingerprint; then
+ one_arg
+
+ fingerprint "$arg1"
+elif test "$command" = ls; then
+ check_type "$arg2"
+
+ cd "$pkidir/${type}ca/incoming"
+ for file in $(glob "$arg1*-req.pem"); do
+ fingerprint $file
+ done
+elif test "$command" = flush; then
+ check_type "$arg1"
+
+ rm -f "$pkidir/${type}ca/incoming/"*
+elif test "$command" = reject; then
+ one_or_two_args
+ check_type "$arg2"
+ resolve_prefix "$arg1"
+
+ rm -f "$req"
+elif test "$command" = approve; then
+ one_or_two_args
+ check_type "$arg2"
+ resolve_prefix "$arg1"
+
+ make_tmpdir
+ cp "$req" "$TMP/$req"
+ verify_fingerprint "$TMP/$req"
+ sign_request "$TMP/$req"
+ rm -f "$req" "$TMP/$req"
+elif test "$command" = prompt; then
+ zero_or_one_args
+ check_type "$arg1"
+
+ make_tmpdir
+ cd "$pkidir/${type}ca/incoming"
+ for req in $(glob "*-req.pem"); do
+ cp "$req" "$TMP/$req"
+
+ cert=$(echo "$pkidir/${type}ca/certs/$req" |
+ sed 's/-req.pem/-cert.pem/')
+ if test -f $cert; then
+ echo "Request $req already approved--dropping duplicate request"
+ rm -f "$req" "$TMP/$req"
+ continue
+ fi
+
+ echo
+ echo
+ fingerprint "$TMP/$req" "$req"
+ printf "Disposition for this request (skip/approve/reject)? "
+ read answer
+ case $answer in
+ approve)
+ echo "Approving $req"
+ sign_request "$TMP/$req" "$cert"
+ rm -f "$req" "$TMP/$req"
+ ;;
+ r*)
+ echo "Rejecting $req"
+ rm -f "$req" "$TMP/$req"
+ ;;
+ *)
+ echo "Skipping $req"
+ ;;
+ esac
+ done
+elif test "$command" = expire; then
+ zero_or_one_args
+ cutoff=$(($(date +%s) - $(parse_age ${arg1-1day})))
+ for type in switch controller; do
+ cd "$pkidir/${type}ca/incoming" || exit 1
+ for file in $(glob "*"); do
+ time=$(date -r "$file" +%s)
+ if test "$time" -lt "$cutoff"; then
+ rm -f "$file"
+ fi
+ done
+ done
+else
+ echo "$0: $command command unknown; use --help for help" >&2
+ exit 1
+fi