summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bays <robert@vyatta.com>2010-07-23 13:07:44 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-07-28 09:51:03 -0700
commit3dd5183a3c52ca16bc7b7461b2a2820fe87ff49d (patch)
treecf2bff1146a85f4ce9214689c902a66d93283792
parent04909ae8013ce8ccd0032f2615c0eef9ad4ceffe (diff)
downloadvyatta-cfg-quagga-3dd5183a3c52ca16bc7b7461b2a2820fe87ff49d.tar.gz
vyatta-cfg-quagga-3dd5183a3c52ca16bc7b7461b2a2820fe87ff49d.zip
fix for bug 5892
(cherry picked from commit 5ae305002d35de573a34974104f13ebede556715)
-rwxr-xr-xscripts/bgp/vyatta-bgp.pl83
-rw-r--r--templates/protocols/bgp/node.tag/neighbor/node.tag/local-as/node.def4
-rw-r--r--templates/protocols/bgp/node.tag/parameters/confederation/peers/node.def1
3 files changed, 67 insertions, 21 deletions
diff --git a/scripts/bgp/vyatta-bgp.pl b/scripts/bgp/vyatta-bgp.pl
index 86ec1e14..d97a3e69 100755
--- a/scripts/bgp/vyatta-bgp.pl
+++ b/scripts/bgp/vyatta-bgp.pl
@@ -1138,7 +1138,7 @@ my %qcom = (
);
my ( $pg, $as, $neighbor );
-my ( $main, $peername, $isneighbor, $checkpeergroups, $checksource, $checklocalas );
+my ( $main, $peername, $isneighbor, $checkpeergroups, $checksource, $isIBGPpeer, $checkforibgpasn);
GetOptions(
"peergroup=s" => \$pg,
@@ -1148,16 +1148,19 @@ GetOptions(
"check-neighbor-ip" => \$isneighbor,
"check-peer-groups" => \$checkpeergroups,
"check-source=s" => \$checksource,
- "check-local-as" => \$checklocalas,
+ "is-iBGP" => \$isIBGPpeer,
+ "check-for-iBGP-ASN=s" => \$checkforibgpasn,
"main" => \$main,
);
-main() if ($main);
-check_peergroup_name($peername) if ($peername);
-check_neighbor_ip($neighbor) if ($isneighbor);
-check_for_peer_groups( $pg, $as ) if ($checkpeergroups);
-check_source($checksource) if ($checksource);
-check_local_as($neighbor, $as) if ($checklocalas);
+main() if ($main);
+check_peergroup_name($peername) if ($peername);
+check_neighbor_ip($neighbor) if ($isneighbor);
+check_for_peer_groups( $pg, $as ) if ($checkpeergroups);
+check_source($checksource) if ($checksource);
+check_for_iBGP_ASN($as, $checkforibgpasn) if ($checkforibgpasn);
+is_IBGP_peer($neighbor, $as) if ($isIBGPpeer);
+
exit 0;
@@ -1293,23 +1296,67 @@ sub check_remote_as {
}
-# Verify that is local-as is used, the peer isn't in a confedration
-sub check_local_as {
+# check to see if this ASN will make a peer an iBGP peer
+sub check_for_iBGP_ASN {
+ my ($as, $testas) = @_;
+ if ("$as" eq "$testas") { exit 1 ; }
+
+ my $config = new Vyatta::Config;
+ $config->setLevel("protocols bgp $as");
+
+ my @neighbors = $config->listNodes('neighbor');
+ foreach $neighbor (@neighbors) {
+ my $remoteas = $config->returnValue("neighbor $neighbor remote-as");
+ if ("$testas" eq "$remoteas") {
+ exit 1;
+ }
+ }
+
+ return;
+}
+
+# is this peer an iBGP peer?
+sub is_IBGP_peer {
my ($neighbor, $as) = @_;
my $config = new Vyatta::Config;
+ my @ibgp_as;
+ my $neighbor_as;
$config->setLevel("protocols bgp $as");
+
+ # find my local ASN for this neighbor
+ # it's either explicitly defined or in the peer-group
+ if ($config->exists("neighbor $neighbor remote-as")) {
+ $neighbor_as = $config->returnValue("neighbor $neighbor remote-as");
+ }
+ elsif ($config->exists("neighbor $neighbor peer-group")) {
+ my $peergroup = $config->returnValue("neighbor $neighbor peer-group");
+ if ($config->exists("peer-group $peergroup remote-as")) {
+ my $peergroup = $config->returnValue("neighbor $neighbor peer-group");
+ $neighbor_as = $config->returnValue("peer-group $peergroup remote-as");
+ }
+ }
+ else {
+ print "Unable to determine primary ASN for neighbor $neighbor\n";
+ exit 1;
+ }
+
+ # now find my possible local ASNs. Confederation ASNs are first.
if ($config->exists('parameters confederation peers')) {
- my @peers = $config->returnValues('parameters confederation peers');
- my $remoteas = $config->returnValue("neighbor $neighbor remote-as");
- foreach my $peeras (@peers) {
- if ("$peeras" eq "$remoteas") {
- print "local-as can't be set for neighbors in a peer group\n";
- return 1;
- }
+ @ibgp_as = $config->returnValues('parameters confederation peers');
+ }
+
+ # push router local ASN on the stack
+ push @ibgp_as, $as;
+
+ # and compare neighbor local as to possible local ASNs
+ foreach my $localas (@ibgp_as) {
+ if ("$localas" eq "$neighbor_as") {
+ exit 1;
}
}
- return 0;
+
+ return;
}
# check that value is either an IPV4 address on system or an interface
diff --git a/templates/protocols/bgp/node.tag/neighbor/node.tag/local-as/node.def b/templates/protocols/bgp/node.tag/neighbor/node.tag/local-as/node.def
index a60b9bb1..42fd3cec 100644
--- a/templates/protocols/bgp/node.tag/neighbor/node.tag/local-as/node.def
+++ b/templates/protocols/bgp/node.tag/neighbor/node.tag/local-as/node.def
@@ -4,6 +4,4 @@ help: Local AS number [REQUIRED]
val_help: u32:1-4294967294; Local AS number
syntax:expression: $VAR(@) >=1 && $VAR(@) <= 4294967294; "local-as must be between 1 and 4294967294"
commit:expression: $VAR(@) != $VAR(../../@); "you can't set local-as the same as the router AS"
-commit:expression: $VAR(../remote-as/@) != $VAR(../../@); "local-as can't be set on iBGP peers"
-commit:expression: exec "/opt/vyatta/sbin/vyatta-bgp.pl --check-local-as --neighbor $VAR(../@) --as $VAR(../../@)"
-
+commit:expression: exec "/opt/vyatta/sbin/vyatta-bgp.pl --is-iBGP --neighbor $VAR(../@) --as $VAR(../../@)"; "local-as can't be set on iBGP peers"
diff --git a/templates/protocols/bgp/node.tag/parameters/confederation/peers/node.def b/templates/protocols/bgp/node.tag/parameters/confederation/peers/node.def
index 71c6b0a8..a5d5b671 100644
--- a/templates/protocols/bgp/node.tag/parameters/confederation/peers/node.def
+++ b/templates/protocols/bgp/node.tag/parameters/confederation/peers/node.def
@@ -3,3 +3,4 @@ type: u32
help: Peer ASs in the BGP confederation
val_help: u32:1-4294967294; Peer AS number numbers (ex: "435 234")
syntax:expression: $VAR(@) >= 1 && $VAR(@) <= 4294967294; "confederation AS id must be between 1 and 4294967294"
+commit:expression: exec "/opt/vyatta/sbin/vyatta-bgp.pl --check-for-iBGP-ASN $VAR(@) --as $VAR(../../../@)"; "can't set confederation ASN to $VAR(@). Delete neighbors with remote-as $VAR(@) first."