Emergency flow cache: Add regression test for emergency flow cache

This commit is contained in:
tyabe
2009-06-26 11:41:07 -07:00
committed by Mikio Hara
parent 292ffb1f39
commit c5ca36a509
13 changed files with 290 additions and 13 deletions
+2 -1
View File
@@ -9,6 +9,7 @@ my $mapFile, $controller;
# Process command line options
unless ( GetOptions( "map=s" => \$mapFile,
"emerg" => \$emerg,
"controller=s", \$controller) ) {
print "unrecognized option\n";
exit 1;
@@ -18,4 +19,4 @@ if ( defined($mapFile) ) {
nftest_process_iface_map($mapFile);
}
setup_kmod($controller);
setup_kmod($controller, $emerg);
+2 -1
View File
@@ -9,6 +9,7 @@ my ($mapFile, $controller);
# Process command line options
unless ( GetOptions( "map=s" => \$mapFile,
"emerg" => \$emerg,
"controller=s", \$controller) ) {
print "unrecognized option\n";
exit 1;
@@ -22,4 +23,4 @@ else {
nftest_process_iface_map("$ENV{'OFT_ROOT'}/bin/veth.map");
}
setup_kmod($controller);
setup_kmod($controller, $emerg);
+2 -1
View File
@@ -13,6 +13,7 @@ print Dumper(@ARGV) . "\n";
# Process command line options
unless ( GetOptions( "map=s" => \$mapFile,
"emerg" => \$emerg,
"controller=s", \$controller) ) {
print "unrecognized option\n";
exit 1;
@@ -22,4 +23,4 @@ if ( defined($mapFile) ) {
nftest_process_iface_map($mapFile);
}
setup_NF2($controller);
setup_NF2($controller, $emerg);
+2 -1
View File
@@ -9,6 +9,7 @@ my ($mapFile, $controller);
# Process command line options
unless ( GetOptions( "map=s" => \$mapFile,
"emerg" => \$emerg,
"controller=s", \$controller) ) {
print "unrecognized option\n";
exit 1;
@@ -18,4 +19,4 @@ if ( defined($mapFile) ) {
nftest_process_iface_map($mapFile);
}
setup_user($controller);
setup_user($controller, $emerg);
+2 -1
View File
@@ -9,6 +9,7 @@ my ($mapFile, $controller);
# Process command line options
unless ( GetOptions( "map=s" => \$mapFile,
"emerg" => \$emerg,
"controller=s", \$controller) ) {
print "unrecognized option\n";
exit 1;
@@ -22,4 +23,4 @@ else {
nftest_process_iface_map("$ENV{'OFT_ROOT'}/bin/veth.map");
}
setup_user($controller);
setup_user($controller, $emerg);
+71 -8
View File
@@ -78,6 +78,9 @@ use Time::HiRes qw(sleep gettimeofday tv_interval usleep);
&create_flow_mod_from_icmp_action
&create_flow_mod_from_icmp
&wait_for_two_flow_expired
&get_dpinst
&wait_for_echo_request
&del_flows
);
my $nf2_kernel_module_path = 'datapath/linux-2.6';
@@ -172,13 +175,16 @@ sub setup_pcap_interfaces {
sub start_ofprotocol {
my ( $dpinst, $controller ) = @_;
if ( !$controller) { $controller = nftest_default_controllers(); }
my $cmd = "${openflow_dir}/secchan/ofprotocol $dpinst $controller --inactivity-probe=999999 &";
print "about to run $cmd\n";
system($cmd);
my ( $dpinst, $controller, $emerg ) = @_;
if ( !$controller) { $controller = nftest_default_controllers(); }
my $cmd;
if (defined $emerg) {
$cmd = "${openflow_dir}/secchan/ofprotocol $dpinst $controller --emerg-flow --inactivity-probe=10 &";
} else {
$cmd = "${openflow_dir}/secchan/ofprotocol $dpinst $controller --inactivity-probe=999999 &";
}
print "about to run $cmd\n";
system($cmd);
}
sub setup_kmod {
@@ -1056,7 +1062,7 @@ sub create_flow_mod_from_udp_action {
flags => $flags,
priority => 0,
buffer_id => -1,
out_port => $enums{'OFPP_NONE'},
out_port => $enums{'OFPP_NONE'}
};
my $flow_mod = $ofp->pack( 'ofp_flow_mod', $flow_mod_args );
my $flow_mod_pkt = combine_args($flow_mod, $mod_type, $out_port, $chg_field, $chg_val);
@@ -1916,5 +1922,62 @@ sub wait_for_two_flow_expired {
sleep 3;
}
sub wait_for_echo_request {
my ( $ofp, $sock, $options_ref, $read_size_ ) = @_;
my $read_size;
if ( defined $read_size_ ) {
$read_size = $read_size_;
} else {
$read_size = 1512;
}
my $recvd_mesg;
sysread( $sock, $recvd_mesg, $read_size )
|| die "Failed to receive ofp_echo_request message: $!";
#print HexDump ($recvd_mesg);
# Inspect message
my $msg_size = length($recvd_mesg);
my $expected_size = $ofp->sizeof('ofp_header');
compare( "ofp_echo_reply msg size", length($recvd_mesg), '==', $expected_size );
my $msg = $ofp->unpack( 'ofp_header', $recvd_mesg );
#print Dumper($msg);
# Verify fields
compare( "header version", $$msg{'version'}, '==', $of_ver );
compare( "header type", $$msg{'type'}, '==', $enums{'OFPT_ECHO_REQUEST'} );
compare( "header length", $$msg{'length'}, '==', $msg_size );
return $$msg{'xid'};
}
sub get_dpinst {
my ($options_ref) = @_;
my $platform = $$options_ref{'common-st-args'};
my $kmod_dpinst = "nl:0";
my $user_dpinst = "unix:/var/run/test";
my $dpinst;
if (($platform eq 'user') or ($platform eq 'user_veth')) {
$dpinst = $user_dpinst;
} else {
$dpinst = $kmod_dpinst;
}
return $dpinst;
}
sub del_flows {
my ($options_ref) = @_;
my $dpinst = get_dpinst($options_ref);
`dpctl del-flows $dpinst`;
}
# Always end library in 1
1;
+4
View File
@@ -527,6 +527,10 @@ sub runTest {
$args .= " --less_ports";
}
if ( defined($commonSTArgs) ) {
$args .= " --common-st-args=$commonSTArgs";
}
if ( -d "$_ROOT_DIR/$projectRoot/$project/$regressRoot/$test" ) {
return runScript( $project, $test, $run, REQUIRED, $args );
}
+1
View File
@@ -229,6 +229,7 @@ sub nftest_init {
"base_idle=i",
"ignore_byte_count",
"num_ports=i",
"common-st-args=s",
"less_ports"
)
)
@@ -0,0 +1,49 @@
#!/usr/bin/perl -w
use Getopt::Long;
use Test::TestLib;
use OF::OFUtil;
my $mapFile;
my $platform;
my $args;
# Process command line options
unless (
GetOptions (
"map=s" => \$mapFile,
"common-st-args=s" => \$platform,
)
)
{
print "invalid command format\n";
exit(1);
}
if (defined($mapFile)) {
$args = "--map=$mapFile";
}
if (!defined($platform)) {
print "no platform defined\n";
exit(1);
}
else {
print "platform = $platform\n";
}
$args .= " --emerg";
my $filename = "of_${platform}_setup.pl";
# exit if of_${platform}_setup.pl not in path
if (-e "$ENV{'OFT_ROOT'}/bin/$filename") {
#system("$filename " . $args . " 2> /dev/null > /dev/null");
system("$ENV{'OFT_ROOT'}/bin/$filename " . $args );
#setup_kmod();
exit (0);
} else {
print "couldn't find setup file $filename\n";
exit (1);
}
@@ -0,0 +1,47 @@
#!/usr/bin/perl -w
use Getopt::Long;
use Test::TestLib;
use OF::OFUtil;
my $mapFile;
my $platform;
my $args;
# Process command line options
unless (
GetOptions (
"map=s" => \$mapFile,
"common-st-args=s" => \$platform,
)
)
{
print "invalid command format\n";
exit(1);
}
if (defined($mapFile)) {
$args = "--map=$mapFile";
}
if (!defined($platform)) {
print "no platform defined\n";
exit(1);
}
else {
print "platform = $platform\n";
}
my $filename = "of_${platform}_teardown.pl";
# exit if of_${platform}_setup.pl not in path
if (-e "$ENV{'OFT_ROOT'}/bin/$filename") {
#system("$filename " . $args . " 2> /dev/null > /dev/null");
system("$ENV{'OFT_ROOT'}/bin/$filename " . $args );
#teardown_kmod();
exit (0);
} else {
print "couldn't find setup file $filename\n";
exit (1);
}
@@ -0,0 +1,105 @@
#!/usr/bin/perl -w
# test_emergency_table
use strict;
use OF::Includes;
use OF::OFUtil;
sub test_emergency_cache_first {
my ( $ofp, $sock, $options_ref, $i, $j, $wildcards ) = @_;
my $max_idle = $$options_ref{'max_idle'};
my $pkt_len = $$options_ref{'pkt_len'};
my $in_port = $i + $$options_ref{'port_base'};
my $out_port = $j + $$options_ref{'port_base'};
my $test_pkt_args = {
DA => "00:00:00:00:00:0" . ( $out_port ),
SA => "00:00:00:00:00:0" . ( $in_port ),
src_ip => "192.168.200." . ( $in_port ),
dst_ip => "192.168.201." . ( $out_port ),
ttl => 64,
len => $pkt_len,
src_port => 70,
dst_port => 80
};
my $test_pkt = new NF2::UDP_pkt(%$test_pkt_args);
print "Set both normal and emergency flow table. Normal key must win\n";
# 1st flow entry -- exact match, normal flow table
my $max_idle_no_expire = 0;
my $normal_wildcards = 0x0; # exact match
my $normal_flags = $enums{'OFPFF_SEND_FLOW_EXP'}; # want flow expiry
my $flow_mod_normal_pkt =
create_flow_mod_from_udp( $ofp, $test_pkt, $in_port, $out_port, $max_idle_no_expire, $normal_flags, $normal_wildcards );
# 2nd flow entry -- wildcard match all, emergency flow table
my $emergency_wildcards = $enums{'OFPFW_ALL'}; # wildcard match all to the all ports
my $emergency_flags = $enums{'OFPFF_EMERG'};
my $flow_mod_emergency_pkt =
create_flow_mod_from_udp( $ofp, $test_pkt, $in_port, $enums{'OFPP_ALL'}, $max_idle, $emergency_flags, $emergency_wildcards );
#print HexDump($flow_mod_normal_pkt);
#print HexDump($flow_mod_emergency_pkt);
# Send 'flow_mod' message
print $sock $flow_mod_normal_pkt;
print "sent flow_mod message (normal table)\n";
# Give OF switch time to process the flow mod
usleep($$options_ref{'send_delay'});
# Send 2nd 'flow_mod' message
print $sock $flow_mod_emergency_pkt;
print "sent flow_mod message (emergency table)\n";
# Give OF switch time to process the flow mod
usleep($$options_ref{'send_delay'});
# Send a packet - ensure packet comes out desired port
print "Verify packets are forwarded correctly\n";
nftest_send( "eth" . ( $i + 1 ), $test_pkt->packed );
nftest_expect( "eth" . ( $j + 1 ), $test_pkt->packed );
# Wait for ECHO_REQUEST but don't reply so that ofprotocol notices disconnection.
wait_for_echo_request ( $ofp, $sock, $options_ref, $ofp->sizeof('ofp_header'));
return $test_pkt;
}
sub test_emergency_cache_second {
my ( $test_pkt, $options_ref, $i, $j ) = @_;
print "sending from $i to $j, but expect the packet from all ports\n";
nftest_send( "eth" . ( $i + 1 ), $test_pkt->packed );
# expect packets on all other interfaces
print "expect multiple packets\n";
for ( my $k = 0 ; $k < $$options_ref{'num_ports'} ; $k++ ) {
if ( $k != $i ) {
nftest_expect( "eth" . ( $k + 1), $test_pkt->packed );
}
}
}
sub my_test {
my ($sock, $options_ref) = @_;
#This test uses two ports
my $inport = 0;
my $outport = 1;
my $wildcards = 0; #exact match
# Wait until switch notices disconnection. it depends on implementation
my $wait_timer = 20;
my $test_pkt = test_emergency_cache_first($ofp, $sock, $options_ref, $inport, $outport, $wildcards);
# Wait until ofprotocol notices that connection is broken
sleep $wait_timer;
# chek if the emergency table has become active
test_emergency_cache_second($test_pkt, $options_ref, $inport, $outport);
}
run_black_box_test( \&my_test, \@ARGV );
@@ -0,0 +1,2 @@
test_emergency_table/run.pl
#test_reconnect/run.pl
+1
View File
@@ -1,2 +1,3 @@
black_box
controller_disconnect
learning_switch