File Coverage

blib/lib/Net/BGP/Router.pm
Criterion Covered Total %
statement 18 84 21.4
branch 0 36 0.0
condition 0 12 0.0
subroutine 6 17 35.2
pod 4 4 100.0
total 28 153 18.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -wT
2              
3             # $Id: Router.pm,v 1.15 2003/06/02 15:01:17 unimlo Exp $
4              
5             package Net::BGP::Router;
6              
7 1     1   1420 use strict;
  1         3  
  1         34  
8 1     1   4 use warnings;
  1         2  
  1         50  
9 1     1   4 use vars qw( $VERSION @ISA );
  1         2  
  1         54  
10              
11             ## Inheritance and Versioning ##
12              
13             $VERSION = '0.04';
14              
15             ## Import modules ##
16              
17 1     1   4 use Net::BGP::RIB;
  1         2  
  1         23  
18 1     1   5 use Scalar::Util qw(weaken);
  1         1  
  1         45  
19 1     1   5 use Carp;
  1         2  
  1         1137  
20              
21             ## Public Class Methods ##
22              
23             sub new
24             {
25 0     0 1   my $proto = shift;
26 0   0       my $class = ref $proto || $proto;
27              
28 0           my $this = {
29             _name => undef,
30             _RIB => new Net::BGP::RIB,
31             _inpeers => {},
32             _outpeers => {},
33             _policy => undef
34             };
35              
36 0           while ( defined(my $arg = shift) ) {
37 0           my $value = shift;
38              
39 0 0         if ( $arg =~ /name/i ) {
    0          
40 0           $this->{_name} = $value;
41             }
42             elsif ( $arg =~ /policy/i ) {
43 0 0         croak "Policy should be a Net::BGP::Policy or sub-class"
44             unless $value->isa('Net::BGP::Policy');
45 0           $this->{_policy} = $value;
46             }
47             else {
48 0           croak "unrecognized argument $arg\n";
49             }
50             }
51              
52 0           bless($this, $class);
53             }
54              
55             ## Public Object Methods ##
56              
57             sub add_peer
58             {
59 0     0 1   my ($this,$peer,$dir,$acl) = @_;
60              
61 0 0         if ($dir =~ /(out|both)/i)
62             {
63             # Policy
64 0 0         $this->{_policy}->set($peer,'out',$acl) if defined $this->{_policy};
65              
66             # RIB
67 0           $this->{_RIB}->add_peer($peer,'out',$acl);
68              
69             # Refresh handler
70 0     0     my $callbackrefresh = sub { $this->_handle_refresh(@_); };
  0            
71 0           $peer->set_refresh_callback($callbackrefresh);
72              
73             # Remember for destruction
74 0           weaken($this->{_outpeers}->{$peer} = $peer);
75             };
76              
77 0 0         if ($dir =~ /(in|both)/i)
78             {
79             # Policy
80 0 0         $this->{_policy}->set($peer,'in',$acl) if defined $this->{_policy};
81              
82             # RIB
83 0           $this->{_RIB}->add_peer($peer,'in',$acl);
84              
85             # Update handler
86 0     0     my $callbackupdate = sub { $this->_handle_update(@_); };
  0            
87 0           $peer->set_update_callback($callbackupdate);
88              
89             # Reset handler
90 0     0     my $callbackreset = sub { $this->_handle_reset(@_); };
  0            
91 0           $peer->set_reset_callback($callbackreset);
92              
93             # Remember for destruction
94 0           weaken($this->{_inpeers}->{$peer} = $peer);
95             };
96             }
97              
98             sub remove_peer
99             {
100 0     0 1   my ($this,$peer,$dir) = @_;
101              
102 0 0         if ($dir =~ /(out|both)/i)
103             {
104             # Callbacks
105 0           $peer->set_refresh_callback(undef);
106              
107             # Policy
108 0 0         $this->{_policy}->delete($peer,'out') if defined $this->{_policy};
109              
110             # RIB
111 0           $this->{_RIB}->remove_peer($peer,'out',$this->{_policy});
112              
113             # Forget!
114 0           delete $this->{_outpeers}->{$peer};
115             };
116              
117 0 0         if ($dir =~ /(in|both)/i)
118             {
119             # Callbacks
120 0           $peer->set_reset_callback(undef);
121 0           $peer->set_update_callback(undef);
122              
123             # Policy
124 0 0         $this->{_policy}->delete($peer,'in') if defined $this->{_policy};
125              
126             # RIB
127 0           $this->{_RIB}->remove_peer($peer,'in',$this->{_policy});
128              
129             # Forget!
130 0           delete $this->{_inpeers}->{$peer};
131             };
132             }
133              
134             sub set_policy
135             {
136 0     0 1   my ($this,$policy,$peer,$dir) = @_;
137 0 0 0       if (! defined $policy || $policy->isa('Net::ACL'))
    0          
138             {
139 0 0 0       croak "Need peer and direction when assigning or removing local policy"
140             unless defined $peer && defined $dir;
141 0 0         croak "No global policy object to modify" unless defined $this->{_policy};
142 0           $this->{_policy}->set($peer,$dir,$policy);
143             }
144             elsif ($policy->isa('Net::BGP::Policy'))
145             {
146 0 0 0       croak "No peer or direction allowed when asigning globel policy"
147             if defined $peer || defined $dir;
148 0           $this->{_policy} = $policy;
149             }
150             else
151             {
152 0           croak "Invalid policy - Need a Net::ACL, a Net::BGP::Policy, or a sub-class of these\n";
153             };
154             }
155              
156             sub DESTROY
157             {
158 0     0     my $this = shift;
159 0           foreach my $peer (values %{$this->{_outpeers}})
  0            
160             {
161 0 0         next unless defined $peer;
162 0           $this->remove_peer($peer,'out');
163             };
164 0           foreach my $peer (values %{$this->{_inpeers}})
  0            
165             {
166 0 0         next unless defined $peer;
167 0           $this->remove_peer($peer,'in');
168             };
169             }
170              
171             ## Private Object Methods ##
172              
173             sub _handle_update
174             {
175 0     0     my ($this,$peer,$update) = @_;
176 0           $this->{_RIB}->handle_update($peer,$update,$this->{_policy});
177             }
178              
179             sub _handle_reset
180             {
181 0     0     my ($this,$peer,$notif) = @_;
182             # The notification packet itself is ignored - But peer is down when we get here!
183 0           warn "GOT RESET: " . $peer->asstring . "\n";
184 0           $this->{_RIB}->reset_peer($peer,'in',$this->{_policy});
185             }
186              
187             sub _handle_refresh
188             {
189 0     0     my ($this,$peer,$refresh) = @_;
190             # The refresh packet itself is ignored - No understading of Address Families yet...
191 0           warn "GOT REFRESH: " . $peer->asstring . "\n";
192 0           $this->{_RIB}->reset_peer($peer,'out',$this->{_policy});
193             }
194              
195             =pod
196              
197             =head1 NAME
198              
199             Net::BGP::Router - A BGP Router based on Net::BGP
200              
201             =head1 SYNOPSIS
202              
203             use Net::BGP::Router;
204              
205             # Constructor
206             $router = new Net::BGP::Router(
207             Name => 'My very own router!',
208             Policy => new Net::BGP::Policy
209             );
210              
211             # Accessor Methods
212             $router->add_peer($peer,'both',$acl);
213             $router->remove_peer($peer,'both');
214             $router->set_policy($policy);
215             $router->set_policy($peer,'in',$acl);
216              
217              
218             =head1 DESCRIPTION
219              
220             This module implement a BGP router. It uses L objects for
221             the BGP sessions and a L object to store the
222             routes. Policy are handled using a L object.
223              
224             =head1 CONSTRUCTOR
225              
226             =over 4
227              
228             =item new() - create a new Net::BGP::Router object
229              
230             $router = new Net::BGP::Router(
231             Name => 'My very own router!',
232             Policy => new Net::BGP::Policy
233             );
234              
235             This is the constructor for Net::BGP::Router object. It returns a
236             reference to the newly created object. The following named parameters may
237             be passed to the constructor:
238              
239             =over 4
240              
241             =item Name
242              
243             This is the name of the router or router-context. This is for informational
244             use only.
245              
246             =item Policy
247              
248             This is the Net::BGP::Policy object used as policy. If not specified, no
249             policy will be used. Note that the Policy method set()
250             will be issued on every add_peer() and remove_peer(). Therefor there is no
251             reason to do this manualy before adding the peers.
252              
253             =back
254              
255             =back
256              
257             =head1 ACCESSOR METHODS
258              
259             =over 4
260              
261             =item add_peer()
262              
263             This method adds a peer to the router. The first argument is the peer object.
264             The second argument is the direction of the peer. A peer can either only
265             contribute with updates C, only recieve updates C, or both C.
266             The third argument is optitional and is a peer/direction-specific policy as
267             a Net::ACL object.
268              
269             =item remove_peer()
270              
271             This medhod removes a peer from the router. The first argument is the peer
272             object. The second argument is the direction in which the peer should be
273             removed.
274              
275             =item set_policy()
276              
277             This medhod can either change the global policy or the policy for a peer in
278             some direction. The first argument is the policy object. If the policy object
279             is a Net::BGP::Policy object, it will be used as a new global policy. If it
280             is a Net::ACL object, it will be used as a peer policy for the peer object and
281             diraction specified as second and third argument.
282              
283             =back
284              
285             =head1 SEE ALSO
286              
287             Net::BGP, Net::BGP::RIB, Net::BGP::Policy, Net::ACL
288              
289             =head1 AUTHOR
290              
291             Martin Lorensen
292              
293             =cut
294              
295             ## End of Net::BGP::Router ##
296              
297             1;