From c329a213592a20c5dbf9b57ffa92f8043efdc706 Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 11 Nov 2021 10:03:54 +0000 Subject: [PATCH] Remove switchd regress tests. --- regress/usr.sbin/Makefile | 3 +- regress/usr.sbin/switchd/Makefile | 77 ---- regress/usr.sbin/switchd/OFP.pm | 426 ------------------ regress/usr.sbin/switchd/Proc.pm | 194 -------- regress/usr.sbin/switchd/Switchd.pm | 75 --- regress/usr.sbin/switchd/args-http.pcap | Bin 4844 -> 0 bytes regress/usr.sbin/switchd/args-http.pm | 63 --- regress/usr.sbin/switchd/args-icmp.pcap | Bin 708 -> 0 bytes regress/usr.sbin/switchd/args-icmp.pm | 47 -- regress/usr.sbin/switchd/args-packet-jumbo.pm | 122 ----- regress/usr.sbin/switchd/run.pl | 352 --------------- 11 files changed, 1 insertion(+), 1358 deletions(-) delete mode 100644 regress/usr.sbin/switchd/Makefile delete mode 100644 regress/usr.sbin/switchd/OFP.pm delete mode 100644 regress/usr.sbin/switchd/Proc.pm delete mode 100644 regress/usr.sbin/switchd/Switchd.pm delete mode 100644 regress/usr.sbin/switchd/args-http.pcap delete mode 100644 regress/usr.sbin/switchd/args-http.pm delete mode 100644 regress/usr.sbin/switchd/args-icmp.pcap delete mode 100644 regress/usr.sbin/switchd/args-icmp.pm delete mode 100644 regress/usr.sbin/switchd/args-packet-jumbo.pm delete mode 100644 regress/usr.sbin/switchd/run.pl diff --git a/regress/usr.sbin/Makefile b/regress/usr.sbin/Makefile index e55a540a464..0e621098d61 100644 --- a/regress/usr.sbin/Makefile +++ b/regress/usr.sbin/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.25 2021/10/02 07:06:13 anton Exp $ +# $OpenBSD: Makefile,v 1.26 2021/11/11 10:03:54 claudio Exp $ SUBDIR += acme-client SUBDIR += arp @@ -14,7 +14,6 @@ SUBDIR += ospf6d SUBDIR += relayd SUBDIR += rpki-client SUBDIR += snmpd -SUBDIR += switchd SUBDIR += syslogd .if ${MACHINE} == "amd64" || ${MACHINE} == "i386" diff --git a/regress/usr.sbin/switchd/Makefile b/regress/usr.sbin/switchd/Makefile deleted file mode 100644 index 478e68e42e8..00000000000 --- a/regress/usr.sbin/switchd/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# $OpenBSD: Makefile,v 1.11 2021/10/11 05:46:42 anton Exp $ - -# The following ports must be installed for the regression tests: -# p5-Net-Pcap Perl interface for libpcap -# p5-NetPacket Perl interface for packet encoding/decoding -# p5-BSD-arc4random Perl interface to the arc4 random number generator -# -# Check wether all required perl packages are installed. If some -# are missing print a warning and skip the tests, but do not fail. - -PERL_REQUIRE != perl -Mstrict -Mwarnings -e ' \ - eval { require NetPacket::Ethernet } or print $@; \ - eval { require Net::Pcap } or print $@; \ - eval { require BSD::arc4random } or print $@; \ -' -.if ! empty (PERL_REQUIRE) -regress: - @echo "${PERL_REQUIRE}" - @echo install these perl packages for additional tests - @echo SKIPPED -.endif - -# Automatically generate regress targets from test cases in directory. - -ARGS != cd ${.CURDIR} && ls args-*.pm -CLEANFILES += stamp-* *.h *.ph *.conf *.log ktrace.out - -SRC_PATH = ${.CURDIR}/../../../usr.sbin/switchd -SYS_PATH = ${.CURDIR}/../../../sys/net -OFP_HEADERS = ofp.h ofp10.h -OFP_PERLHEADERS = ${OFP_HEADERS:S/.h/.ph/} - -# Set variables so that make runs with and without obj directory. -# Only do that if necessary to keep visible output short. - -.if ${.CURDIR} == ${.OBJDIR} -PERLINC = -I. -PERLPATH = -.else -PERLINC = -I${.CURDIR} -I${.OBJDIR} -PERLPATH = ${.CURDIR}/ -.endif - -# The arg tests take a perl hash with arguments controlling the -# test parameters. Generally they consist of switch, switchd. - -.for a in ${ARGS} -REGRESS_TARGETS += run-$a -run-$a: $a - time SUDO="${SUDO}" KTRACE=${KTRACE} SWITCHD=${SWITCHD} \ - perl ${PERLINC} ${PERLPATH}run.pl ${PERLPATH}$a -.endfor - -${OFP_HEADERS}: -.for p in ${SRC_PATH} ${SYS_PATH} - ! test -s $p/$@ || grep -v '^#include' $p/$@ >$@ -.endfor - -.SUFFIXES: .h .ph -.h.ph: - @h2ph -d ${.OBJDIR} $< - -REGRESS_SETUP = ${OFP_PERLHEADERS} - -# make perl syntax check for all args files - -.PHONY: syntax - -syntax: stamp-syntax - -stamp-syntax: ${ARGS} -.for a in ${ARGS} - @perl -c ${PERLPATH}$a -.endfor - @date >$@ - -.include diff --git a/regress/usr.sbin/switchd/OFP.pm b/regress/usr.sbin/switchd/OFP.pm deleted file mode 100644 index be6112a3e24..00000000000 --- a/regress/usr.sbin/switchd/OFP.pm +++ /dev/null @@ -1,426 +0,0 @@ -# -# NetPacket::OFP - Decode and encode OpenFlow packets. -# - -package NetPacket::OFP; - -# -# Copyright (c) 2016 Reyk Floeter . -# -# This package is free software and is provided "as is" without express -# or implied warranty. It may be used, redistributed and/or modified -# under the terms of the Perl Artistic License (see -# http://www.perl.com/perl/misc/Artistic.html) -# - -use strict; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); -use NetPacket; - -my $myclass; -BEGIN { - $myclass = __PACKAGE__; - $VERSION = "0.01"; -} -sub Version () { "$myclass v$VERSION" } - -BEGIN { - @ISA = qw(Exporter NetPacket); - - @EXPORT = qw(); - - @EXPORT_OK = qw(ofp_strip); - - %EXPORT_TAGS = ( - ALL => [@EXPORT, @EXPORT_OK], - strip => [qw(ofp_strip)], - ); -} - -# -# Get aligned packet size -# - -sub ofp_align { - my $matchlen = shift; - - return (($matchlen + (8 - 1)) & (~(8 - 1))); -} - -# -# Decode the packet -# - -sub decode { - my $class = shift; - my($pkt, $parent, @rest) = @_; - my $self = {}; - - # Class fields - $self->{_parent} = $parent; - $self->{_frame} = $pkt; - - $self->{version} = 1; - $self->{type} = 0; - $self->{length} = 0; - $self->{xid} = 0; - $self->{data} = ''; - - # Decode OpenFlow packet - if (defined($pkt)) { - ($self->{version}, $self->{type}, $self->{length}, - $self->{xid}, $self->{data}) = unpack("CCnNa*", $pkt); - } - - # Return a blessed object - bless($self, $class); - - return ($self); -} - -# -# Strip header from packet and return the data contained in it -# - -undef &udp_strip; -*ofp_strip = \&strip; - -sub strip { - my ($pkt, @rest) = @_; - my $ofp_obj = decode($pkt); - return ($ofp_obj->data); -} - -# -# Encode a packet -# - -sub encode { - my $class = shift; - my $self = shift; - my $pkt = ''; - my $datalen = length($self->{data}); - - if ($self->{length} == 0) { - $self->{length} = 8 + $datalen; - } - - if ($datalen == 0) { - $pkt = pack('CCnN', $self->{version}, $self->{type}, - $self->{length}, $self->{xid}); - } else { - $pkt = pack('CCnNa*', $self->{version}, $self->{type}, - $self->{length}, $self->{xid}, $self->{data}); - } - - return ($pkt); -} - -# -# Table property Multipart reply -# - -sub ofp_table_property { - my $tp_type = shift; - my $tp_payload = shift; - my $tp_header; - my ($datalen, $pad); - - # len = header + payload - $datalen = 4 + length($tp_payload); - - $tp_header = pack('nna*', - $tp_type, # type - $datalen, # length - $tp_payload # payload - ); - - $pad = ofp_align($datalen) - $datalen; - if ($pad > 0) { - $tp_header .= pack("x[$pad]"); - } - - return ($tp_header); -} - -sub ofp_table_features_reply { - my $class = shift; - my $self = shift; - my $pkt = NetPacket::OFP->decode() or fatal($class, "new packet"); - my ($tf_header, $tf_payload); - my ($tp_header, $tp_payload); - my $mp_header; - - $tf_payload = ''; - - # - # instructions - # - $tp_payload = ''; - for (my $inst = main::OFP_INSTRUCTION_T_GOTO_TABLE(); - $inst <= main::OFP_INSTRUCTION_T_METER(); $inst++) { - $tp_payload .= pack('nn', - $inst, # type - 4 # length - ); - } - - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_INSTRUCTION(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_INSTRUCTION_MISS(), - $tp_payload); - - # - # Next tables - # - $tp_payload = ''; - - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_NEXT_TABLES(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_NEXT_TABLES_MISS(), - $tp_payload); - - # - # Write / Apply actions - # - $tp_payload = pack('nn', - main::OFP_ACTION_OUTPUT(), # type - 4, # length - ); - $tp_payload .= pack('nn', - main::OFP_ACTION_PUSH_VLAN(), # type - 4, # length - ); - $tp_payload .= pack('nn', - main::OFP_ACTION_POP_VLAN(), # type - 4, # length - ); - - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_WRITE_ACTIONS(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_WRITE_ACTIONS_MISS(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_APPLY_ACTIONS(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_APPLY_ACTIONS_MISS(), - $tp_payload); - - # - # Match/Wildcards/Write set-field/Apply set-field - # - $tp_payload = pack('nCC', - main::OFP_OXM_C_OPENFLOW_BASIC(), # class - main::OFP_XM_T_IN_PORT() << 1, # type - 4, # length - ); - $tp_payload .= pack('nCC', - main::OFP_OXM_C_OPENFLOW_BASIC(), # class - main::OFP_XM_T_ETH_TYPE() << 1, # type - 4, # length - ); - $tp_payload .= pack('nCC', - main::OFP_OXM_C_OPENFLOW_BASIC(), # class - main::OFP_XM_T_ETH_SRC() << 1, # type - 4, # length - ); - $tp_payload .= pack('nCC', - main::OFP_OXM_C_OPENFLOW_BASIC(), # class - main::OFP_XM_T_ETH_DST() << 1, # type - 4, # length - ); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_MATCH(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_WILDCARDS(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_WRITE_SETFIELD(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_APPLY_SETFIELD(), - $tp_payload); - $tf_payload .= - ofp_table_property(main::OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS(), - $tp_payload); - - # - # Finish - # - $tf_header = pack('nCx[5]a[32]NNNNNN', - 64 + length($tf_payload), # length - 0, # tableid - 'start', # name - 0x00000000, 0x00000000, # metadata_match - 0x00000000, 0x00000000, # metadata_write - 0x00000000, # config - 10000 # max_entries - ); - $tf_header .= $tf_payload; - # XXX everything fits a single multipart reply, for now. - - $mp_header = pack('nnx[4]', - main::OFP_MP_T_TABLE_FEATURES(), # multipart type - 0 # multipart flags - ); - - $mp_header .= $tf_header; - - $pkt->{version} = $self->{version}; - $pkt->{type} = main::OFP_T_MULTIPART_REPLY(); - $pkt->{xid} = $self->{xid}++; - $pkt->{data} = $mp_header; - $pkt = NetPacket::OFP->encode($pkt); - - main::ofp_output($self, $pkt); - - # Wait for new flow-mod - main::ofp_input($self); -} - -# -# Module initialisation -# - -1; - -# autoloaded methods go after the END token (&& pod) below - -__END__ - -=head1 NAME - -C - Assemble and disassemble OpenFlow packets. - -=head1 SYNOPSIS - - use NetPacket::OFP; - - $ofp_obj = NetPacket::OFP->decode($raw_pkt); - $ofp_pkt = NetPacket::OFP->encode($ofp_obj); - $ofp_data = NetPacket::OFP::strip($raw_pkt); - -=head1 DESCRIPTION - -C provides a set of routines for assembling and -disassembling packets using OpenFlow. - -=head2 Methods - -=over - -=item Cdecode([RAW PACKET])> - -Decode the raw packet data given and return an object containing -instance data. This method will quite happily decode garbage input. -It is the responsibility of the programmer to ensure valid packet data -is passed to this method. - -=item Cencode($ofp_obj)> - -Return a OFP packet encoded with the instance data specified. - -=back - -=head2 Functions - -=over - -=item C - -Return the encapsulated data (or payload) contained in the OpenFlow -packet. This data is suitable to be used as input for other -C modules. - -This function is equivalent to creating an object using the -C constructor and returning the C field of that -object. - -=back - -=head2 Instance data - -The instance data for the C object consists of -the following fields. - -=over - -=item version - -The OpenFlow version. - -=item type - -The message type. - -=item length - -The total message length. - -=item xid - -The transaction Id. - -=item data - -The encapsulated data (payload) for this packet. - -=back - -=head2 Exports - -=over - -=item default - -none - -=item exportable - -ofp_strip - -=item tags - -The following tags group together related exportable items. - -=over - -=item C<:strip> - -Import the strip function C. - -=item C<:ALL> - -All the above exportable items. - -=back - -=back - -=head1 COPYRIGHT - - Copyright (c) 2016 Reyk Floeter - - This package is free software and is provided "as is" without express - or implied warranty. It may be used, redistributed and/or modified - under the terms of the Perl Artistic License (see - http://www.perl.com/perl/misc/Artistic.html) - -=head1 AUTHOR - -Reyk Floeter Ereyk@openbsd.orgE - -=cut - -# any real autoloaded methods go after this line diff --git a/regress/usr.sbin/switchd/Proc.pm b/regress/usr.sbin/switchd/Proc.pm deleted file mode 100644 index 5dc55953f1d..00000000000 --- a/regress/usr.sbin/switchd/Proc.pm +++ /dev/null @@ -1,194 +0,0 @@ -# $OpenBSD: Proc.pm,v 1.2 2021/10/11 05:46:42 anton Exp $ - -# Copyright (c) 2010-2017 Alexander Bluhm -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -use strict; -use warnings; - -package Proc; -use Carp; -use Errno; -use IO::File; -use POSIX; -use Time::HiRes qw(time alarm sleep); - -my %CHILDREN; - -sub kill_children { - my @pids = @_ ? @_ : keys %CHILDREN - or return; - my @perms; - foreach my $pid (@pids) { - if (kill(TERM => $pid) != 1 and $!{EPERM}) { - push @perms, $pid; - } - } - if (my @sudo = split(' ', $ENV{SUDO}) and @perms) { - local $?; # do not modify during END block - my @cmd = (@sudo, '/bin/kill', '-TERM', @perms); - system(@cmd); - } - delete @CHILDREN{@pids}; -} - -BEGIN { - $SIG{TERM} = $SIG{INT} = sub { - my $sig = shift; - kill_children(); - $SIG{TERM} = $SIG{INT} = 'DEFAULT'; - POSIX::raise($sig); - }; -} - -END { - kill_children(); - $SIG{TERM} = $SIG{INT} = 'DEFAULT'; -} - -sub new { - my $class = shift; - my $self = { @_ }; - $self->{down} ||= "Shutdown"; - $self->{func} && ref($self->{func}) eq 'CODE' - or croak "$class func not given"; - $self->{logfile} - or croak "$class log file not given"; - open(my $fh, '>', $self->{logfile}) - or die "$class log file $self->{logfile} create failed: $!"; - $fh->autoflush; - $self->{log} = $fh; - $self->{ppid} = $$; - return bless $self, $class; -} - -sub run { - my $self = shift; - - pipe(my $reader, my $writer) - or die ref($self), " pipe to child failed: $!"; - defined(my $pid = fork()) - or die ref($self), " fork child failed: $!"; - if ($pid) { - $CHILDREN{$pid} = 1; - $self->{pid} = $pid; - close($reader); - $self->{pipe} = $writer; - return $self; - } - %CHILDREN = (); - $SIG{TERM} = $SIG{INT} = 'DEFAULT'; - $SIG{__DIE__} = sub { - die @_ if $^S; - warn @_; - IO::Handle::flush(\*STDERR); - POSIX::_exit(255); - }; - open(STDERR, '>&', $self->{log}) - or die ref($self), " dup STDERR failed: $!"; - close($writer); - open(STDIN, '<&', $reader) - or die ref($self), " dup STDIN failed: $!"; - close($reader); - - do { - $self->child(); - print STDERR $self->{up}, "\n"; - $self->{func}->($self); - } while ($self->{redo}); - print STDERR "Shutdown", "\n"; - - IO::Handle::flush(\*STDOUT); - IO::Handle::flush(\*STDERR); - POSIX::_exit(0); -} - -sub wait { - my $self = shift; - my $flags = shift; - - # if we a not the parent process, assume the child is still running - return 0 unless $self->{ppid} == $$; - - my $pid = $self->{pid} - or croak ref($self), " no child pid"; - my $kid = waitpid($pid, $flags); - if ($kid > 0) { - my $status = $?; - my $code; - $code = "exit: ". WEXITSTATUS($?) if WIFEXITED($?); - $code = "signal: ". WTERMSIG($?) if WIFSIGNALED($?); - $code = "stop: ". WSTOPSIG($?) if WIFSTOPPED($?); - delete $CHILDREN{$pid} if WIFEXITED($?) || WIFSIGNALED($?); - return wantarray ? ($kid, $status, $code) : $kid; - } - return $kid; -} - -sub loggrep { - my $self = shift; - my($regex, $timeout) = @_; - - my $end; - $end = time() + $timeout if $timeout; - - do { - my($kid, $status, $code) = $self->wait(WNOHANG); - if ($kid > 0 && $status != 0 && !$self->{dryrun}) { - # child terminated with failure - die ref($self), " child status: $status $code"; - } - open(my $fh, '<', $self->{logfile}) - or die ref($self), " log file open failed: $!"; - my @match = grep { /$regex/ } <$fh>; - return wantarray ? @match : $match[0] if @match; - close($fh); - # pattern not found - if ($kid == 0) { - # child still running, wait for log data - sleep .1; - } else { - # child terminated, no new log data possible - return; - } - } while ($timeout and time() < $end); - - return; -} - -sub up { - my $self = shift; - my $timeout = shift || 10; - $self->loggrep(qr/$self->{up}/, $timeout) - or croak ref($self), " no '$self->{up}' in $self->{logfile} ". - "after $timeout seconds"; - return $self; -} - -sub down { - my $self = shift; - my $timeout = shift || 30; - $self->loggrep(qr/$self->{down}/, $timeout) - or croak ref($self), " no '$self->{down}' in $self->{logfile} ". - "after $timeout seconds"; - return $self; -} - -sub kill_child { - my $self = shift; - kill_children($self->{pid}); - return $self; -} - -1; diff --git a/regress/usr.sbin/switchd/Switchd.pm b/regress/usr.sbin/switchd/Switchd.pm deleted file mode 100644 index 3fb227e9012..00000000000 --- a/regress/usr.sbin/switchd/Switchd.pm +++ /dev/null @@ -1,75 +0,0 @@ -# $OpenBSD: Switchd.pm,v 1.2 2021/10/11 05:46:42 anton Exp $ - -# Copyright (c) 2010-2017 Alexander Bluhm -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -use strict; -use warnings; - -package Switchd; -use parent 'Proc'; -use Carp; -use Cwd; -use Sys::Hostname; -use File::Basename; - -sub new { - my $class = shift; - my %args = @_; - $args{logfile} ||= "switchd.log"; - $args{up} ||= $args{dryrun} || "listen on "; - $args{down} ||= $args{dryrun} ? "switchd.conf:" : "parent terminating"; - $args{func} = sub { Carp::confess "$class func may not be called" }; - $args{conffile} ||= "switchd.conf"; - my $self = Proc::new($class, %args); - $self->{listenaddr} - or croak "$class listen addr not given"; - $self->{listenport} - or croak "$class listen port not given"; - - # substitute variables in config file - my $curdir = dirname($0) || "."; - my $objdir = getcwd(); - my $hostname = hostname(); - (my $host = $hostname) =~ s/\..*//; - my $listenaddr = $self->{listenaddr}; - my $listenport = $self->{listenport}; - - my $test = basename($self->{testfile} || ""); - open(my $fh, '>', $self->{conffile}) - or die ref($self), " conf file $self->{conffile} create failed: $!"; - - my $config = "# regress $test\n"; - $config .= "listen on $self->{listenaddr} port $self->{listenport}\n" - unless $self->{conf} && $self->{conf} =~ /^listen /; - $config .= $self->{conf} if $self->{conf}; - $config =~ s/(\$[a-z]+)/$1/eeg; - print $fh $config; - close $fh; - - return $self; -} - -sub child { - my $self = shift; - my @sudo = $ENV{SUDO} ? split(' ', $ENV{SUDO}) : (); - my @ktrace = $ENV{KTRACE} ? ($ENV{KTRACE}, "-i") : (); - my $switchd = $ENV{SWITCHD} ? $ENV{SWITCHD} : "switchd"; - my @cmd = (@sudo, @ktrace, $switchd, "-dvv", "-f", $self->{conffile}); - print STDERR "execute: @cmd\n"; - exec @cmd; - die ref($self), " exec '@cmd' failed: $!"; -} - -1; diff --git a/regress/usr.sbin/switchd/args-http.pcap b/regress/usr.sbin/switchd/args-http.pcap deleted file mode 100644 index 0938907fb8e355b94293bfeda6b5f9ac6b0dfe1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4844 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 azjoXi2CL(UP5 -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -package args_http; - -use strict; -use warnings; -use base qw(Exporter); -our @EXPORT = qw(init next); - -my $topology = { - hosts => { - "6c8814709208" => { - "port" => 8 - }, - "3431c4778157" => { - "port" => 24 - } - } -}; - -sub init { - my $class = shift; - my $sock = shift; - my $self = { "count" => 0, "pcap" => "args-http.pcap", - "sock" => $sock, "version" => main::OFP_V_1_0() }; - - bless($self, $class); - - main::ofp_hello($self); - - return ($self); -} - -sub next { - my $class = shift; - my $self = shift; - my $src; - - $self->{count}++; - - $src = $topology->{hosts}->{$self->{eh}->{src_mac}}; - if ($src) { - $self->{port} = $src->{port}; - } - - main::ofp_packet_in($self, $self->{data}); -} - -1; diff --git a/regress/usr.sbin/switchd/args-icmp.pcap b/regress/usr.sbin/switchd/args-icmp.pcap deleted file mode 100644 index 6da899c3554d8108f99b6b8be3a26c82ae8b948e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmca|c+)~A1{MYwxWLZ9zzF2rjq3{+-pb361Z0CSgH~2~*`9#!OAoE(u8~ zX&G5Lc?Cr!WffI5bq!4|Z5>@beFH-yV-r&|bC8YCw;^nV*afi{Vk5{I7L2c!gKPuY z%D|99k&X9&HXhl7uo2UbO>aSdT(A@2#~D39KQco7C=BvrwaoU}ZvveT -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -package args_icmp; - -use strict; -use warnings; -use base qw(Exporter); -our @EXPORT = qw(init next); - -sub init { - my $class = shift; - my $sock = shift; - my $self = { "count" => 0, "pcap" => "args-icmp.pcap", - "sock" => $sock, "version" => main::OFP_V_1_0() }; - - bless($self, $class); - - main::ofp_hello($self); - - return ($self); -} - -sub next { - my $class = shift; - my $self = shift; - - $self->{count}++; - $self->{port} = $self->{count} % 2; - - main::ofp_packet_in($self, $self->{data}); -} - -1; diff --git a/regress/usr.sbin/switchd/args-packet-jumbo.pm b/regress/usr.sbin/switchd/args-packet-jumbo.pm deleted file mode 100644 index 83da592f657..00000000000 --- a/regress/usr.sbin/switchd/args-packet-jumbo.pm +++ /dev/null @@ -1,122 +0,0 @@ -# $OpenBSD: args-packet-jumbo.pm,v 1.4 2016/11/17 14:37:55 rzalamena Exp $ - -# Copyright (c) 2016 Reyk Floeter -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -package args_packet_jumbo; - -use strict; -use warnings; -use base qw(Exporter); -our @EXPORT = qw(init next); - -my $topology = { - buffers => {}, - hosts => { - "a00000000001" => { - "port" => 1 - }, - "a00000000002" => { - "port" => 2 - }, - "a00000000003" => { - "port" => 3 - } - }, - packets => [ - { - "src_mac" => "a00000000001", - "dest_mac" => "a00000000002", - "src_ip" => "10.0.0.1", - "src_port" => 12345, - "dest_ip" => "10.0.0.2", - "dest_port" => 80, - "length" => 2048, - "count" => 3, - "ofp_response" => main::OFP_T_PACKET_OUT() - }, - { - "src_mac" => "a00000000002", - "dest_mac" => "a00000000001", - "src_ip" => "10.0.0.2", - "src_port" => 80, - "dest_ip" => "10.0.0.1", - "dest_port" => 12345, - "length" => 17000, - "count" => 3, - "ofp_response" => main::OFP_T_FLOW_MOD() - - }, - { - "src_mac" => "a00000000001", - "dest_mac" => "ffffffffffff", - "src_ip" => "10.0.0.1", - "dest_ip" => "10.255.255.255", - "length" => 65451, - "count" => 3, - "ofp_response" => main::OFP_T_PACKET_OUT() - } - ] -}; - -sub init { - my $class = shift; - my $sock = shift; - my $self = { "count" => 0, - "sock" => $sock, "version" => main::OFP_V_1_3() }; - - bless($self, $class); - main::ofp_hello($self); - - for (my $i = 0; $i < @{$topology->{packets}}; $i++) { - my $packet = $topology->{packets}[$i]; - my $src = $topology->{hosts}->{$packet->{src_mac}}; - - $self->{port} = $src->{port} if ($src); - - for (my $j = 0; $j < $packet->{count}; $j++) { - my $ofp; - $self->{count}++; - $ofp = main::packet_send($self, $packet); - - if (not defined($packet->{ofp_response})) { - continue; - } - - if ($ofp->{type} != $packet->{ofp_response}) { - main::fatal($class, - "invalid ofp response type " . - $ofp->{type}); - } - - # Flow-mod also expects an packet-out. - if ($packet->{ofp_response} == main::OFP_T_FLOW_MOD()) { - $ofp = main::ofp_input($self); - if ($ofp->{type} != main::OFP_T_PACKET_OUT()) { - main::fatal($class, - "invalid ofp response type " . - $ofp->{type}); - } - } - } - } - - return ($self); -} - -sub next { - # Not used -} - -1; diff --git a/regress/usr.sbin/switchd/run.pl b/regress/usr.sbin/switchd/run.pl deleted file mode 100644 index e087f834228..00000000000 --- a/regress/usr.sbin/switchd/run.pl +++ /dev/null @@ -1,352 +0,0 @@ -#!/usr/bin/perl -# $OpenBSD: run.pl,v 1.12 2018/12/03 22:41:00 bluhm Exp $ - -# Copyright (c) 2017 Alexander Bluhm -# Copyright (c) 2016 Reyk Floeter -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -use strict; -use warnings; -use File::Basename; -use IO::Socket::INET; -use Net::Pcap; -use NetPacket::Ethernet; -use NetPacket::IP; -use NetPacket::UDP; -use BSD::arc4random qw(arc4random arc4random_uniform arc4random_bytes); - -use Switchd; - -BEGIN { - require OFP; - require 'ofp.ph'; - require 'ofp10.ph'; -} - -sub fatal { - my $class = shift; - my $err = shift; - print STDERR "*** ".$class.": ".$err."\n"; - die($err); -} - -sub ofp_debug { - my $dir = shift; - my $ofp = shift; - - fatal("OFP", "empty response") if (!$ofp->{version}); - - printf("OFP ".$dir." version %d type %d length %d xid %d\n", - $ofp->{version}, - $ofp->{type}, - $ofp->{length}, - $ofp->{xid}); - -} - -sub ofp_input { - my $self = shift; - my $pkt; - my $pktext; - my $ofp; - my $ofplen; - - # Read the OFP payload head - $self->{sock}->recv($pkt, 8); - $ofp = NetPacket::OFP->decode($pkt) or - fatal('ofp_input', 'Failed to decode OFP header'); - - # Read the body and decode it. - $ofplen = $ofp->{length}; - if (defined($ofplen) && $ofplen > 8) { - $ofplen -= 8; - - # Perl recv() only reads 16k at a time, so loop here. - while ($ofplen > 0) { - $self->{sock}->recv($pktext, $ofplen); - if (length($pktext) == 0) { - fatal('ofp_input', 'Socket closed'); - } - $ofplen -= length($pktext); - $pkt .= $pktext; - } - - $ofp = NetPacket::OFP->decode($pkt) or - fatal('ofp_input', 'Failed to decode OFP'); - } - ofp_debug('<', $ofp); - - return ($ofp); -} - -sub ofp_output { - my $self = shift; - my $pkt = shift; - my $ofp = NetPacket::OFP->decode($pkt); - - ofp_debug('>', $ofp); - $self->{sock}->send($pkt); -} - -sub ofp_match_align { - my $matchlen = shift; - - return (($matchlen + (8 - 1)) & (~(8 - 1))); -} - -sub ofp_hello { - my $class; - my $self = shift; - my $hello = NetPacket::OFP->decode() or fatal($class, "new packet"); - my $features; - my $pkt; - - $hello->{version} = $self->{version}; - $hello->{type} = OFP_T_HELLO(); - $hello->{xid} = $self->{xid}++; - $pkt = NetPacket::OFP->encode($hello); - - # XXX timeout - ofp_output($self, $pkt); - $hello = ofp_input($self); - - # OpenFlow >= 1.3 wants features, set-config and table features. - if ($self->{version} == OFP_V_1_3()) { - $features = ofp_input($self); - if ($features->{type} != OFP_T_FEATURES_REQUEST()) { - fatal($class, 'Unexpected packet type ' . - $features->{type}); - } - - $pkt = NetPacket::OFP->decode() or - fatal($class, 'new packet'); - $pkt->{version} = $self->{version}; - $pkt->{type} = OFP_T_FEATURES_REPLY(); - $pkt->{xid} = $features->{xid}; - $pkt->{data} = pack('NNNCCxxNN', - 0x00FFAABB, 0xCCDDEEFF, # datapath_id - 0, # nbuffers - 1, # ntables - 0, # aux_id - 0x00000001, # capabilities - 0x00000001 # actions - ); - ofp_output($self, NetPacket::OFP->encode($pkt)); - - # Just read set-config and table features request - ofp_input($self); - ofp_input($self); - - # Answer the table features so switchd(8) install table-miss - NetPacket::OFP->ofp_table_features_reply($self); - } - - return ($hello); -} - -sub ofp_packet_in { - my $class; - my $self = shift; - my $data = shift; - my $pktin = NetPacket::OFP->decode() or fatal($class, "new packet"); - my $pkt; - - if ($self->{version} == OFP_V_1_0()) { - $pkt = pack('NnnCxa*', - OFP_PKTOUT_NO_BUFFER(), # buffer_id - length($data), # total_len - $self->{port} || OFP_PORT_NORMAL(), # port - OFP_PKTIN_REASON_NO_MATCH(), # reason - $data # data - ); - } else { - my $match = pack('nCCN', - OFP_OXM_C_OPENFLOW_BASIC(), # class - OFP_XM_T_IN_PORT(), # field + mask - 4, # length - $self->{port} || OFP_PORT_NORMAL() # in_port - ); - # matchlen is OXMs + ofp_match header. - my $matchlen = 4 + length($match); - my $padding = ofp_match_align($matchlen) - $matchlen; - if ($padding > 0) { - $match .= pack("x[$padding]"); - } - - $pkt = pack('NnCCNNnna*xxa*', - OFP_PKTOUT_NO_BUFFER(), # buffer_id - length($data), # total_len - OFP_PKTIN_REASON_NO_MATCH(), # reason - 0, # table_id - 0x00000000, 0x00000000, # cookie - OFP_MATCH_OXM(), # match_type - $matchlen, # match_len - $match, # OXM matches - $data # data - ); - } - - $pktin->{version} = $self->{version}; - $pktin->{type} = OFP_T_PACKET_IN(); - $pktin->{xid} = $self->{xid}++; - $pktin->{data} = $pkt; - $pkt = NetPacket::OFP->encode($pktin); - - # XXX timeout - ofp_output($self, $pkt); - return (ofp_input($self)); -} - -sub packet_send { - my $class; - my $self = shift; - my $packet = shift; - my $eth; - my $ip; - my $udp; - my $data; - my $pkt; - my $src; - - # Payload - $data = arc4random_bytes($packet->{length}); - - # IP header - $ip = NetPacket::IP->decode(); - $ip->{src_ip} = $packet->{src_ip} || "127.0.0.1"; - $ip->{dest_ip} = $packet->{dest_ip} || "127.0.0.1"; - $ip->{ver} = NetPacket::IP::IP_VERSION_IPv4; - $ip->{hlen} = 5; - $ip->{tos} = 0; - $ip->{id} = arc4random_uniform(2**16); - $ip->{ttl} = 0x5a; - $ip->{flags} = 0; #XXX NetPacket::IP::IP_FLAG_DONTFRAG; - $ip->{foffset} = 0; - $ip->{proto} = NetPacket::IP::IP_PROTO_UDP; - $ip->{options} = ''; - - # UDP header - $udp = NetPacket::UDP->decode(); - $udp->{src_port} = $packet->{src_port} || 9000; - $udp->{dest_port} = $packet->{dest_port} || 9000; - $udp->{data} = $data; - - $ip->{data} = $udp->encode($ip); - $pkt = $ip->encode() or fatal($class, "ip"); - - # Create Ethernet header - $self->{data} = pack('H12H12na*' , - $packet->{dest_mac}, - $packet->{src_mac}, - NetPacket::Ethernet::ETH_TYPE_IP, - $pkt); - - return (main::ofp_packet_in($self, $self->{data})); -} - -sub packet_decode { - my $pkt = shift; - my $hdr = shift; - my $eh = NetPacket::Ethernet->decode($pkt); - - printf("%s %s %04x %d", - join(':', unpack '(A2)*', $eh->{src_mac}), - join(':', unpack '(A2)*', $eh->{dest_mac}), - $eh->{type}, length($pkt)); - if (length($pkt) < $hdr->{len}) { - printf("/%d", $hdr->{len}) - } - printf("\n"); - - return ($eh); -} - -sub process { - my $sock = shift; - my $path = shift; - my $pcap_t; - my $err; - my $pkt; - my %hdr; - my ($filename, $dirs, $suffix) = fileparse($path, ".pm"); - (my $func = $filename) =~ s/-/_/g; - my $state; - local $@; - - print "- $filename\n"; - - require $path or fatal("main", $path); - - eval { - $state = $func->init($sock); - }; - die if($@); - - return if not $state->{pcap}; - - $pcap_t = Net::Pcap::open_offline($dirs."".$state->{pcap}, \$err) - or fatal("main", $err); - - while ($pkt = Net::Pcap::next($pcap_t, \%hdr)) { - - $state->{data} = $pkt; - $state->{eh} = packet_decode($pkt, \%hdr); - - eval { - $func->next($state); - }; - die if($@); - } - - Net::Pcap::close($pcap_t); -} - -if (@ARGV < 1) { - print "\nUsage: run.pl test.pl\n"; - exit; -} - -# Flush after every write -$| = 1; - -my $test = $ARGV[0]; -my @test_files = (); -for (@ARGV) { - push(@test_files, glob($_)); -} - -my $sd = Switchd->new( - listenaddr => "127.0.0.1", - listenport => 6633, - testfile => $test, -); -$sd->run->up; - -# Open connection to the controller -my $sock = IO::Socket::INET->new( - PeerHost => "127.0.0.1", - PeerPort => 6633, - Proto => 'tcp', -) or fatal("main", "ERROR in Socket Creation : $!\n"); - -# Run all requested tests -for my $test_file (@test_files) { - process($sock, $test_file); -} - -$sock->close(); - -$sd->kill_child->down; - -1; -- 2.20.1