summaryrefslogtreecommitdiff
path: root/scripts/bgp/vyatta-bgp.pl
blob: 2f54140726d1993c38a4051ff0917c8ba8d99e4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/perl
use strict;
use lib "/opt/vyatta/share/perl5/";
use Vyatta::Config;
use Vyatta::Misc;
use Getopt::Long;
use NetAddr::IP::Lite;

my ( $pg, $as, $neighbor );
my ( $checkas, $peername, $checkifpeergroup, $checkpeergroups, $checksource );

GetOptions(
    "peergroup=s"         => \$pg,
    "as=s"                => \$as,
    "neighbor=s"          => \$neighbor,
    "check-peer-name=s"   => \$peername,
    "check-as"            => \$checkas,
    "check-peer-groups"   => \$checkpeergroups,
    "check-if-peer-group" => \$checkifpeergroup,
    "check-source=s"	  => \$checksource,
);

check_peer_name($peername)	  	if ($peername);
check_for_peer_groups( $pg, $as )	if ($checkpeergroups);
check_as( $neighbor, $as, $pg ) 	if ($checkas);
check_if_peer_group($pg)		if ($checkifpeergroup);
check_source($checksource)	        if ($checksource);

exit 0;

sub check_if_peer_group {
    my $neighbor = shift;

    exit 1 if is_ip_v4_or_v6($neighbor);
    exit 0;
}

# Make sure the neighbor is a proper IP or name
sub check_peer_name {
    my $neighbor = shift;

    $_ = $neighbor;
    my $version = is_ip_v4_or_v6($neighbor);
    if ( ( !defined($version) ) && (/[\s\W]/g) ) {
        die "malformed neighbor address $neighbor\n";
    }

    # Quagga treats the first byte as a potential IPv6 address
    # so we can't use it as a peer group name.  So let's check for it.
    if ( $version == 6 && /^[A-Fa-f]{1,4}$/ ) {
	die "malformed neighbor address $neighbor\n";
    }
}

# Make sure we aren't deleteing a peer-group that has
# neighbors configured to us it
sub check_for_peer_groups {
    my $config = new Vyatta::Config;
    my $pg     = shift;
    die "Peer group not defined\n" unless $pg;
    my $as = shift;
    die "AS not defined\n" unless $as;
    my @peers;

    # short circuit if the neighbor is an IP rather than name
    return if is_ip_v4_or_v6($pg);

    # get the list of neighbors and see if they have a peer-group set
    $config->setLevel("protocols bgp $as neighbor");
    my @neighbors = $config->listNodes();

    foreach my $node (@neighbors) {
        my $peergroup = $config->returnValue("$node peer-group");
        if ( $peergroup eq $pg ) { push @peers, $node; }
    }

    # if we found peers in the previous statements
    # notify an return errors
    if (@peers) {
        foreach my $node (@peers) {
            print "neighbor $node uses peer-group $pg\n";
        }

	die "please delete these peers before removing the peer-group\n";
    }
}

# make sure nodes are either in a peer group or have
# a remote AS assigned to them.
sub check_as {
    my ($neighbor, $as, $pg) = @_;

    die "neighbor not defined\n" unless $neighbor;
    die "AS not defined\n" unless $as;

    # if this is peer-group then short circuit this
    return if ! is_ip_v4_or_v6($neighbor); 

    my $config = new Vyatta::Config;
    $config->setLevel("protocols bgp $as neighbor $neighbor");
    my $remoteas = $config->returnValue("remote-as");
    return if defined $remoteas;

    return if $pg;

    my $peergroup   = $config->returnValue("peer-group");
    die "protocols bgp $as neighbor $neighbor: must define a remote-as or peer-group\n"
      unless $peergroup;

    my $peergroupas = $config->returnValue(" .. $peergroup remote-as");
    die "protocols bgp $as neighbor $neighbor: must define a remote-as in neighbor or peer-group $peergroup\n"
      unless $peergroupas;
}

# check that value is either an IPV4 address on system or an interface
sub check_source {
    my $src = shift;
    my $ip = new NetAddr::IP::Lite($src);
    
    if ($ip) {
	my $found = grep { my $a = new NetAddr::IP::Lite($_);
			   $a->addr() eq $ip->addr() } Vyatta::Misc::getIP();
	die "IP address $ip does not exist on this system\n" if ($found == 0);
    } else {
	my $found = grep { $_ eq $src } Vyatta::Misc::getInterfaces();
	die "Interface $src does not exist on the system\n" if ($found == 0);
    }
}