From: bluhm Date: Fri, 16 Jan 2015 17:06:43 +0000 (+0000) Subject: Add test that exchanges database description packets with ospfd. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=414a9b5818fd13bc861ad125ae1d11b95e05dfc0;p=openbsd Add test that exchanges database description packets with ospfd. From Florian Riehm. --- diff --git a/regress/usr.sbin/ospfd/Client.pm b/regress/usr.sbin/ospfd/Client.pm index ef0e1fb0af5..fad2248a2d7 100644 --- a/regress/usr.sbin/ospfd/Client.pm +++ b/regress/usr.sbin/ospfd/Client.pm @@ -1,7 +1,7 @@ -# $OpenBSD: Client.pm,v 1.3 2014/08/18 22:58:19 bluhm Exp $ +# $OpenBSD: Client.pm,v 1.4 2015/01/16 17:06:43 bluhm Exp $ -# Copyright (c) 2010-2014 Alexander Bluhm -# Copyright (c) 2014 Florian Riehm +# Copyright (c) 2010-2015 Alexander Bluhm +# Copyright (c) 2014-2015 Florian Riehm # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,7 @@ use strict; use warnings; +use feature "state"; package Client; use parent 'Proc'; @@ -84,6 +85,8 @@ sub handle_ip { "ospfd area is $ospf{area_id_str}: expected $area"); if ($ospf{type} == 1) { handle_hello(); + } elsif ($ospf{type} == 2) { + handle_dd(); } else { warn "ospf type is not supported: $ospf{type}"; } @@ -123,7 +126,43 @@ sub handle_hello { } if ($reason) { print "wait for hello because of: $reason\n"; - } else { + } elsif (!$wait || $wait->{dr} || $wait->{bdr} || $wait->{nbrs}) { + $cv->send(); + } +} + +sub handle_dd { + my %dd = consume_dd(\$handle->{rbuf}); + + my $compare = sub { + my $expect = shift; + foreach my $key (qw(options bits)) { + if ($expect->{"dd_$key"}) { + $dd{$key} == $expect->{"dd_$key"} or + return sprintf("dd key '%s' is 0x%x: expected 0x%x\n", + $key, $dd{$key}, $expect->{"dd_$key"}); + } + } + if ($expect->{dd_seq}) { + $dd{dd_sequence_number} == $expect->{dd_seq} or + return sprintf("dd_sequence_number is 0x%x: expected 0x%x\n", + $dd{dd_sequence_number}, $expect->{dd_seq}); + } + return ""; + }; + + my $error = $compare->($check); + return $cv->croak("check: $error") if $error; + print "check dd successful\n"; + + my $reason; + if ($wait) { + $reason = $compare->($wait); + } + if ($reason) { + print "wait for dd because of: $reason\n"; + } elsif (!$wait || $wait->{dd_bits} || $wait->{dd_options} || + $wait->{dd_seq}) { $cv->send(); } } @@ -193,6 +232,51 @@ sub interface_state_machine { return \%state; } +sub send_dd { + my $state = shift; + my $ip_number = unpack("N", pack("C4", split(/\./, $ism_ip))); + my $ip = join(".", unpack("C4", pack("N", $ip_number))); + my $rtrid_number = unpack("N", pack("C4", split(/\./, $ism_rtrid))); + my $rtrid = join(".", unpack("C4", pack("N", $rtrid_number))); + state $dd_count = 0; + + my %ether = ( + src_str => $ism_mac, + dst_str => "01:00:5e:00:00:05", # don't know the real dst mac + type => 0x0800, # ipv4 + ); + my %ip = ( + v => 4, # ipv4 + hlen => 20, + tos => 0xc0, + id => $dd_count++, # increment for debugging + off => 0, # no fragment + ttl => 1, # only for direct connected + p => 89, # protocol ospf + src_str => $ip, + dst_str => $ospfd_ip, + ); + my %ospf = ( + version => 2, # ospf v2 + type => 2, # dd + router_id_str => $rtrid, + area_id_str => $area, + autype => 0, # no authentication + ); + my %dd = ( + interface_mtu => 1500, + options => 0x02, + bits => $state->{dd_bits}, + dd_sequence_number => 999, # some value + ); + $handle->push_write( + construct_ether(\%ether, + construct_ip(\%ip, + construct_ospf(\%ospf, + construct_dd(\%dd)))) + ); +} + sub ism_set_state { my $state = shift; @@ -200,6 +284,10 @@ sub ism_set_state { for (my $i = 0; $i < @states; $i++) { $isms[$i] ||= interface_state_machine(); %{$isms[$i]} = (%{$isms[$i]}, %{$states[$i]}); + if ($states[$i]{dd_bits}) { + send_dd($states[$i]); + delete $states[$i]{dd_bits}; + } } } diff --git a/regress/usr.sbin/ospfd/LICENSE b/regress/usr.sbin/ospfd/LICENSE index ff350f9632f..8b9a9229f26 100644 --- a/regress/usr.sbin/ospfd/LICENSE +++ b/regress/usr.sbin/ospfd/LICENSE @@ -1,5 +1,5 @@ -# Copyright (c) 2010-2014 Alexander Bluhm -# Copyright (c) 2014 Florian Riehm +# Copyright (c) 2010-2015 Alexander Bluhm +# Copyright (c) 2014-2015 Florian Riehm # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/regress/usr.sbin/ospfd/Makefile b/regress/usr.sbin/ospfd/Makefile index a87e748fc05..60718027768 100644 --- a/regress/usr.sbin/ospfd/Makefile +++ b/regress/usr.sbin/ospfd/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.3 2014/11/25 23:13:54 daniel Exp $ +# $OpenBSD: Makefile,v 1.4 2015/01/16 17:06:43 bluhm Exp $ # The following ports must be installed for the regression tests: # p5-AnyEvent provide framework for multiple event loops # p5-Hash-Merge merge associative arrays -# p5-YAML YAML ain't a markup language +# p5-YAML YAML ain't a markup language # # Check wether all required perl packages are installed. If some # are missing print a warning and skip the tests, but do not fail. diff --git a/regress/usr.sbin/ospfd/Packet.pm b/regress/usr.sbin/ospfd/Packet.pm index 28c02a5f60e..7933cb7a682 100644 --- a/regress/usr.sbin/ospfd/Packet.pm +++ b/regress/usr.sbin/ospfd/Packet.pm @@ -1,6 +1,7 @@ -# $OpenBSD: Packet.pm,v 1.2 2014/07/11 22:28:51 bluhm Exp $ +# $OpenBSD: Packet.pm,v 1.3 2015/01/16 17:06:43 bluhm Exp $ -# Copyright (c) 2014 Alexander Bluhm +# Copyright (c) 2014-2015 Alexander Bluhm +# Copyright (c) 2015 Florian Riehm # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -27,11 +28,13 @@ our @EXPORT = qw( consume_ip consume_ospf consume_hello + consume_dd construct_ether construct_arp construct_ip construct_ospf construct_hello + construct_dd ); sub ip_checksum { @@ -227,6 +230,21 @@ sub consume_hello { return %fields; } +sub consume_dd { + my $packet = shift; + + length($$packet) >= 8 + or croak "dd packet too short: ". length($$packet); + my $dd = substr($$packet, 0, 8, ""); + my %fields; + @fields{qw(interface_mtu options bits dd_sequence_number)} = + unpack("n C C N", $dd); + $fields{bits} <= 7 + or croak "All bits except of I-, M- and MS-bit must be zero"; + + return %fields; +} + sub construct_hello { my $fields = shift; @@ -255,4 +273,13 @@ sub construct_hello { return $packet; } +sub construct_dd { + my $fields = shift; + + my $packet = pack("n C C N", + @$fields{qw(interface_mtu options bits dd_sequence_number)}); + + return $packet; +} + 1; diff --git a/regress/usr.sbin/ospfd/args-ddstate.pl b/regress/usr.sbin/ospfd/args-ddstate.pl new file mode 100644 index 00000000000..72ed496fdf2 --- /dev/null +++ b/regress/usr.sbin/ospfd/args-ddstate.pl @@ -0,0 +1,44 @@ +use strict; +use warnings; +use Default qw($ospfd_ip $ospfd_rtrid); + +our %tst_args = ( + client => { + tasks => [ + { + name => "receive hello with dr 0.0.0.0 bdr 0.0.0.0, ". + "enter $ospfd_rtrid as our neighbor", + check => { + dr => "0.0.0.0", + bdr => "0.0.0.0", + nbrs => [], + }, + state => { + nbrs => [ $ospfd_rtrid ], + }, + }, + { + name => "neighbor asserting itself as master. " . + "We proclaim to be master, because of higher router id.", + wait => { + dd_bits => 7, # I|M|MS + }, + state => { + dd_bits => 7, + }, + timeout => 10, # not specified in rfc + }, + { + name => "check if neighbor is slave, initialization is done ". + "and neighbour has applied our dd sequence number.", + wait => { + dd_bits => 0x2, # M + dd_seq => 999, + }, + timeout => 10, # not specified in rfc + }, + ], + }, +); + +1; diff --git a/regress/usr.sbin/ospfd/args-ifstate-ism2.pl b/regress/usr.sbin/ospfd/args-ifstate-ism2.pl index ce236c11bbf..aa53bcf23d6 100644 --- a/regress/usr.sbin/ospfd/args-ifstate-ism2.pl +++ b/regress/usr.sbin/ospfd/args-ifstate-ism2.pl @@ -2,7 +2,6 @@ use strict; use warnings; -use Client; use Default qw($ospfd_ip $ospfd_rtrid); our %tst_args = ( diff --git a/regress/usr.sbin/ospfd/args-ifstate-pri-ism-ospfd.pl b/regress/usr.sbin/ospfd/args-ifstate-pri-ism-ospfd.pl index 20966a6301b..f9c57757067 100644 --- a/regress/usr.sbin/ospfd/args-ifstate-pri-ism-ospfd.pl +++ b/regress/usr.sbin/ospfd/args-ifstate-pri-ism-ospfd.pl @@ -4,7 +4,6 @@ use strict; use warnings; -use Client; use Default qw($area $tun_number $ospfd_ip $ospfd_rtrid); our %tst_args = ( diff --git a/regress/usr.sbin/ospfd/args-ifstate-pri-ism.pl b/regress/usr.sbin/ospfd/args-ifstate-pri-ism.pl index bd0e0c67104..f0c32777f86 100644 --- a/regress/usr.sbin/ospfd/args-ifstate-pri-ism.pl +++ b/regress/usr.sbin/ospfd/args-ifstate-pri-ism.pl @@ -4,7 +4,6 @@ use strict; use warnings; -use Client; use Default qw($area $tun_number $ospfd_ip $ospfd_rtrid); our %tst_args = ( diff --git a/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd-ism.pl b/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd-ism.pl index b451e5b03ac..f1de202bc66 100644 --- a/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd-ism.pl +++ b/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd-ism.pl @@ -4,7 +4,6 @@ use strict; use warnings; -use Client; use Default qw($area $tun_number $ospfd_ip $ospfd_rtrid); our %tst_args = ( diff --git a/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd.pl b/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd.pl index 146680b7f55..8f2eb16550c 100644 --- a/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd.pl +++ b/regress/usr.sbin/ospfd/args-ifstate-pri-ospfd.pl @@ -4,7 +4,6 @@ use strict; use warnings; -use Client; use Default qw($area $tun_number $ospfd_ip $ospfd_rtrid); our %tst_args = ( diff --git a/regress/usr.sbin/ospfd/args-ifstate.pl b/regress/usr.sbin/ospfd/args-ifstate.pl index 430d38f2c21..e504bb364d3 100644 --- a/regress/usr.sbin/ospfd/args-ifstate.pl +++ b/regress/usr.sbin/ospfd/args-ifstate.pl @@ -1,6 +1,5 @@ use strict; use warnings; -use Client; use Default qw($ospfd_ip $ospfd_rtrid); our %tst_args = ( diff --git a/regress/usr.sbin/ospfd/args-none.pl b/regress/usr.sbin/ospfd/args-none.pl index edfd7986fbc..bebb3935e31 100644 --- a/regress/usr.sbin/ospfd/args-none.pl +++ b/regress/usr.sbin/ospfd/args-none.pl @@ -3,7 +3,6 @@ use strict; use warnings; -use Client; use Default qw($ospfd_ip); our %tst_args = (