Emergency flow cache: Add regression test for emergency flow cache
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+105
@@ -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,2 +1,3 @@
|
||||
black_box
|
||||
controller_disconnect
|
||||
learning_switch
|
||||
|
||||
Reference in New Issue
Block a user