diff options
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." |