summaryrefslogtreecommitdiff
path: root/scripts/bgp/vyatta-bgp.pl
blob: 6f72a5c5fb4379845e9c7b8b72a1b5e0974e5fea (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
129
130
131
132
133
134
135
#!/usr/bin/perl
use lib "/opt/vyatta/share/perl5/";
use VyattaConfig;
use VyattaMisc;
use Getopt::Long;

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

if    (defined $peername) 	 	{ check_peer_name($peername); }
elsif (defined $checkpeergroups &&
       defined $pg &&
       defined $as) 			{ check_for_peer_groups($pg, $as); }
elsif (defined $neighbor && 
       defined $as && 
       defined $checkas && 
       defined $pg) 		 	{ check_as($pg, $neighbor, $as); }
elsif (defined $neighbor && 
       defined $as && 
       defined $checkas)  	 	{ check_as(-1, $neighbor, $as); }
elsif (defined $pg &&
       defined $checkifpeergroup)       { check_if_peer_group($pg); }


exit 0;

sub check_if_peer_group {
    my $neighbor = shift;

    my $version = is_ip_v4_or_v6($neighbor);
    exit 1 if defined $version;
    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)) { 
    print "malformed neighbor address $neighbor\n";
    exit 1;
  }
  
  # 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}$/) {
    print "malformed neighbor address $neighbor\n";
    exit 1;
  }
}

# Make sure we aren't deleteing a peer-group that has 
# neighbors configured to us it
sub check_for_peer_groups() {
  my $config = new VyattaConfig;
  my $pg = shift;
  my $as = shift;
  my $node = $pg;
  my @peers, @neighbors;

  # short circuit if the neighbor is an IP rather than name
  my $version = is_ip_v4_or_v6($node);
  return if defined $version;

  # 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 $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 $node (@peers) {
      print "neighbor $node uses peer-group $pg\n";
    }
    
    print "please delete these peers before removing the peer-group\n";
    exit 1;
  }

  return;
}

# make sure nodes are either in a peer group of have
# a remote AS assigned to them.  
sub check_as() {
  my $pg = shift;
  my $neighbor = shift;
  my $as = shift;
  my $config = new VyattaConfig;
  my $pgtest = $neighbor;

  # if this is peer-group then short circuit this
  my $version = is_ip_v4_or_v6($node);
  return if ! defined $version;

  $config->setLevel("protocols bgp $as neighbor $neighbor");
  $remoteas = $config->returnValue("remote-as");

  if (! defined $remoteas) {
    if ($pg > 0) { 
      $peergroup = 1; 
      $peergroupas = 1;
    }
    else { 
      $peergroup = $config->returnValue("peer-group"); 
      $peergroupas = $config->returnValue(" .. $peergroup remote-as");
    }

    if (! defined $peergroup) {
      print "protocols bgp $as neighbor $neighbor: you must define a remote-as or peer-group\n";
      exit 1;
    }

    if (! defined $peergroupas) {
      print "protocols bgp $as neighbor $neighbor: you must define a remote-as in this neighbor or in peer-group $peergroup\n";
      exit 1;
    }
  }

  return;
}