#!/usr/bin/perl -wT
# $Id: 50-BGP.t,v 1.1 2003/10/27 23:57:14 unimlo Exp $
use strict;
use Test::More tests => 22;
# Use
use_ok('Net::BGP');
use_ok('Net::BGP::ASPath');
use_ok('Net::BGP::NLRI');
use_ok('Net::BGP::Update');
use_ok('Net::BGP::Notification');
use_ok('Net::BGP::Refresh');
use_ok('Net::BGP::Peer');
use_ok('Net::BGP::Process');
# What's happening here?
# ======================
# Two peers in same process connects - one is passive and listning
# the other active and not listning.
#
# On recieving the 2nd keepalive message the listner sends an UPDATE
# message and a REFRESH-message.
#
# On recieving the REFRESH-message, the active peer stops the
# connection and remove it self from the BGP process.
#
# The Cease notification also makes the listning peer remove it self
# from the BGP process.
#
# Along with this, the listning peer has a user timer that is called
# 2 times with atleast 1 second between.
my $lh1 = '127.0.0.1';
my $lh2 = '127.0.0.1'; # Windows don't know of 127.0.0.2!
my $port = 10179; # > 1024 to allow non-root execution
#my $port = 179; # 179 for debuging!
my $keepalive = 5; # To allow faster execution. Must long enough to allow code to execute!
# Construction
my $bgp = new Net::BGP::Process(
Port => $port
);
ok(ref $bgp eq 'Net::BGP::Process','process construction');
my $listen = new Net::BGP::Peer(
Start => 1,
Listen => 1,
Passive => 1,
ThisID => $lh1,
ThisAS => 65001,
PeerID => $lh2,
PeerAS => 65002,
PeerPort=> $port,
Refresh => 1,
KeepAliveTime => $keepalive
);
ok(ref $listen eq 'Net::BGP::Peer','listing peer construction');
my $active = new Net::BGP::Peer(
Start => 1,
Listen => 0,
Passive => 0,
ThisID => $lh2,
ThisAS => 65002,
PeerID => $lh1,
PeerAS => 65001,
PeerPort=> $port,
Refresh => 1,
KeepaliveTime => $keepalive
);
ok(ref $active eq 'Net::BGP::Peer','active peer construction');
my $msg = join('',map { pack('H2',$_); } qw (
00 00 00 14 40 01 01 00 40 02 06 02 02 FD EB FD
EA 40 03 04 0A FF 67 01 18 0A 02 01
));
my $update = Net::BGP::Update->_new_from_msg($msg);
$listen->add_timer(\&timer,1);
$listen->set_open_callback(\&opencallback);
$listen->set_keepalive_callback(\&keepcallback);
$active->set_update_callback(\&updatecallback);
$active->set_refresh_callback(\&refreshcallback);
$listen->set_reset_callback(\&resetcallback);
$active->set_reset_callback(\&resetcallback);
$listen->set_notification_callback(\¬ifcallback);
$active->set_notification_callback(\¬ifcallback);
$listen->set_error_callback(\&errorcallback);
$active->set_error_callback(\&errorcallback);
$bgp->add_peer($listen);
$bgp->add_peer($active);
my ($openok,$keepok,$updateok,$estabok,$refreshok,$shutlok,$shutaok,$timerok,$resetaok,$resetlok) = (0,0,0,0,0,0,0,0,0,0);
my $keepseq = 0;
print "# Main BGP test may take between $keepalive and " . $keepalive*3 . " seconds\n";
eval
{
local $SIG{ALRM} = sub
{
$bgp->remove_peer($listen);
$bgp->remove_peer($active);
die "time-out\n";
};
alarm $keepalive*3-1;
$bgp->event_loop();
alarm 0;
};
if ($@)
{
die unless $@ eq "time-out\n"; # propagate unexpected errors
fail('Time-out! BGP test failed!');
}
else
{
pass('event_loop finished');
};
ok($openok, 'Open callback');
ok($keepok, 'Keepalive callback');
ok($updateok, 'Update callback');
ok($estabok, 'Refresh callback (established)');
ok($refreshok, 'Refresh callback (refresh request)');
ok($resetlok, 'Reset listner');
ok($resetaok, 'Reset active');
ok($shutlok == 2,'Shutdown listner');
ok($shutaok == 2,'Shutdown active');
ok($timerok == 2,'Timer');
## End of test script - Functions below ##
sub opencallback
{
my ($peer) = @_;
$openok = ref $peer eq 'Net::BGP::Peer';
};
sub keepcallback
{
my ($peer) = @_;
if ($keepseq == 1)
{
$keepok = ref $peer eq 'Net::BGP::Peer';
};
if ($timerok == 2)
{
$peer->update($update);
$peer->refresh();
$peer->set_keepalive_callback(undef);
};
$keepseq += 1 unless $keepseq == 2;
}
sub updatecallback
{
my ($peer,$update) = @_;
$updateok = ref $peer eq 'Net::BGP::Peer';
$updateok &&= $update->_encode_message eq $msg;
}
sub refreshcallback
{
my ($peer,$refresh) = @_;
unless (defined $refresh)
{
$estabok = 1;
return;
};
$refreshok = ref $peer eq 'Net::BGP::Peer';
$refreshok &&= ref $refresh eq 'Net::BGP::Refresh';
$peer->stop;
}
sub resetcallback
{
my ($peer) = @_;
if ($peer eq $listen)
{
$resetlok = 1;
}
elsif ($peer eq $active)
{
$resetaok = 1;
}
else
{
fail('Unknown peer in reset-callback');
}
}
sub notifcallback
{
my ($peer,$error) = @_;
if ($peer eq $listen)
{
$shutlok = $error->error_code() == 6;
$shutlok &&= $error->error_subcode() == 0;
$bgp->remove_peer($peer);
}
elsif ($peer eq $active)
{
fail('Acrive peer in notification-callback');
}
else
{
fail('Unknown peer in notification-callback');
};
};
sub errorcallback
{
my ($peer,$error) = @_;
if ($peer eq $listen)
{
$shutlok &&= $error->error_code() == 6;
$shutlok &&= $error->error_subcode() == 0;
$shutlok = 2 if $shutlok;
}
elsif ($peer eq $active)
{
$shutaok = $error->error_code() == 6;
$shutaok &&= $error->error_subcode() == 0;
$shutaok = 2 if $shutaok;
$peer->set_error_callback(undef);
$bgp->remove_peer($peer);
}
else
{
fail('Unknown peer in error-callback');
};
};
sub timer
{
my ($peer) = @_;
$timerok += 1;
$timerok = 0 unless $peer eq $listen;
$peer->remove_timer(\&timer) if ($timerok == 2);
};
__END__
syntax highlighted by Code2HTML, v. 0.9.1