summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2022-10-18 12:25:54 +0300
committerzsdc <taras@vyos.io>2022-10-18 12:25:54 +0300
commitf78ad4c4c4cb94fe6bf321d9a6b8f54328b4cb79 (patch)
tree0115c871bf76cb11516c0968340fad12e76097ad
parentd4097690c40f619bc0e78a0d674985f7880a19a3 (diff)
downloadvyatta-cfg-quagga-f78ad4c4c4cb94fe6bf321d9a6b8f54328b4cb79.tar.gz
vyatta-cfg-quagga-f78ad4c4c4cb94fe6bf321d9a6b8f54328b4cb79.zip
bgp listen: T1875: added BGP listen range feature
This change provides the same CLI structure as in 1.4 for the `protocols bgp listen` and must be fully compatible with future releases (no additional migration is required).
-rwxr-xr-xscripts/bgp/vyatta-bgp.pl116
-rw-r--r--templates/protocols/bgp/node.tag/listen/limit/node.def4
-rw-r--r--templates/protocols/bgp/node.tag/listen/node.def1
-rw-r--r--templates/protocols/bgp/node.tag/listen/range/node.def7
-rw-r--r--templates/protocols/bgp/node.tag/listen/range/node.tag/peer-group/node.def5
5 files changed, 127 insertions, 6 deletions
diff --git a/scripts/bgp/vyatta-bgp.pl b/scripts/bgp/vyatta-bgp.pl
index 3e49e1d1..9b8d0a3a 100755
--- a/scripts/bgp/vyatta-bgp.pl
+++ b/scripts/bgp/vyatta-bgp.pl
@@ -687,6 +687,26 @@ my %qcom = (
set => 'router bgp #3 ; neighbor #5 weight #7',
del => 'router bgp #3 ; no neighbor #5 weight',
},
+ 'protocols bgp var listen' => {
+ set => undef,
+ del => undef,
+ },
+ 'protocols bgp var listen limit' => {
+ set => 'router bgp #3 ; bgp listen limit #6',
+ del => 'router bgp #3 ; no bgp listen limit #6',
+ },
+ 'protocols bgp var listen range' => {
+ set => undef,
+ del => undef,
+ },
+ 'protocols bgp var listen range var' => {
+ set => undef,
+ del => undef,
+ },
+ 'protocols bgp var listen range var peer-group' => {
+ set => 'router bgp #3 ; bgp listen range #6 peer-group #8',
+ del => 'router bgp #3 ; no bgp listen range #6 peer-group #8',
+ },
'protocols bgp var parameters' => {
set => undef,
del => undef,
@@ -1219,7 +1239,8 @@ if ( ! -e "/usr/sbin/zebra" ) {
my ( $pg, $as, $neighbor );
my ( $main, $peername, $isneighbor, $checkpeergroups, $checkpeergroups6, $checksource,
- $isiBGPpeer, $wasiBGPpeer, $confedibgpasn, $listpeergroups, $checkremoteas, $checkbfdpeer, $checkbfdgroup);
+ $isiBGPpeer, $wasiBGPpeer, $confedibgpasn, $listpeergroups, $checkremoteas, $checkbfdpeer, $checkbfdgroup,
+ $checkbgplisten);
GetOptions(
"peergroup=s" => \$pg,
@@ -1237,6 +1258,7 @@ GetOptions(
"check-remote-as=s" => \$checkremoteas,
"check-bfd-peer=s" => \$checkbfdpeer,
"check-peer-group-bfd=s" => \$checkbfdgroup,
+ "check-bgp-listen" => \$checkbgplisten,
"main" => \$main,
);
@@ -1253,6 +1275,7 @@ list_peer_groups($as) if ($listpeergroups);
check_remote_as($checkremoteas) if ($checkremoteas);
check_bfd_peer($checkbfdpeer) if ($checkbfdpeer);
check_bfd_group($checkbfdgroup, $as) if ($checkbfdgroup);
+check_bgp_listen($as) if ($checkbgplisten);
exit 0;
@@ -1359,15 +1382,15 @@ sub check_for_peer_groups {
my @peers;
# get the list of neighbors and see if they have a peer-group set
- $config->setLevel("protocols bgp $as neighbor");
- my @neighbors = $config->listNodes();
+ $config->setLevel("protocols bgp $as");
+ my @neighbors = $config->listNodes("neighbor");
foreach my $node (@neighbors) {
- my $peergroup = $config->returnValue("$node peer-group");
+ my $peergroup = $config->returnValue("neighbor $node peer-group");
if ((defined $peergroup) && ($peergroup eq $pg)) { push @peers, $node; }
- $peergroup = $config->returnValue("$node interface peer-group");
+ $peergroup = $config->returnValue("neighbor $node interface peer-group");
if ((defined $peergroup) && ($peergroup eq $pg)) { push @peers, $node; }
- $peergroup = $config->returnValue("$node interface v6only peer-group");
+ $peergroup = $config->returnValue("neighbor $node interface v6only peer-group");
if ((defined $peergroup) && ($peergroup eq $pg)) { push @peers, $node; }
}
@@ -1380,6 +1403,17 @@ sub check_for_peer_groups {
die "please delete these peers before removing the peer-group\n";
}
+
+ # check BGP listen ranges
+ if ($config->exists("listen range")) {
+ my @listen_ranges = $config->listNodes("listen range");
+ foreach my $range (@listen_ranges) {
+ my $peer_group = $config->returnValue("listen range $range peer-group");
+ if ($pg eq $peer_group) {
+ die "BGP peer-group $peer_group is used for BGP listen range $range and cannot be deleted\n";
+ }
+ }
+ }
}
# function to verify changing remote-as from/to i/eBGP
@@ -1805,6 +1839,74 @@ sub check_bfd_group {
}
}
+# check if ranges are overlapped
+sub ranges_overlapped {
+ my @ranges = @_;
+
+ foreach my $range (@ranges) {
+ foreach my $range_other (@ranges) {
+ if ($range_other != $range) {
+ my $first_address = $range->network();
+ my $last_address = $range->broadcast();
+ my $first_address_other = $range_other->network();
+ my $last_address_other = $range_other->broadcast();
+
+ if (($first_address >= $first_address_other and $first_address <= $last_address_other) or
+ ($last_address >= $first_address_other and $last_address <= $last_address_other)) {
+ # ranges are overlapped
+ print "Listen ranges cannot overlap: $range and $range_other\n";
+ return 1;
+ }
+ }
+ }
+ }
+ # return undef if ranges are not overlapped
+ return undef;
+}
+
+# check BGP listen options
+sub check_bgp_listen {
+ my $as = shift;
+ die "AS not defined\n" unless $as;
+ my @listen_ranges;
+ my @ranges_v4;
+ my @ranges_v6;
+
+ # get a list of ranges
+ my $config = new Vyatta::Config;
+ $config->setLevel("protocols bgp $as");
+ if ($config->exists("listen range")) {
+ @listen_ranges = $config->listNodes("listen range");
+ }
+
+ foreach my $range (@listen_ranges) {
+ # check if a peer-group is changed - this is not supported by FRR,
+ # a listen range must be removed and added with a new peer-group in two commits
+ if ($config->isChanged("listen range $range peer-group") and not $config->isAdded("listen range $range") ) {
+ die "A peer-group cannot be changed. A listen range $range needs to be removed and added again with the new peer-group\n";
+ }
+
+ # check if a peer-group is defined
+ if (not $config->exists("listen range $range peer-group")) {
+ die "A peer-group must be configured for range $range\n";
+ }
+
+ # sort IPv4 and IPv6 ranges
+ my $range_netaddr = new NetAddr::IP::Lite($range);
+ if ($range_netaddr->version() == 4) {
+ push(@ranges_v4, $range_netaddr);
+ }
+ if ($range_netaddr->version() == 6) {
+ push(@ranges_v6, $range_netaddr);
+ }
+ }
+
+ # check if listen ranges are not overlapped
+ if (ranges_overlapped(@ranges_v4) or ranges_overlapped(@ranges_v6)) {
+ die "Configuration error\n";
+ }
+}
+
sub main
{
# initialize the Quagga Config object with data from Vyatta config tree
@@ -1834,6 +1936,7 @@ sub main
# notice the extra space in the level string. keeps the parent from being deleted.
$qconfig->deleteConfigTreeRecursive('protocols bgp var neighbor var', undef, \@ordered) || die "exiting $?\n";
+ $qconfig->deleteConfigTreeRecursive('protocols bgp var listen') || die "exiting $?\n";
$qconfig->deleteConfigTreeRecursive('protocols bgp var peer-group var', undef, \@ordered) || die "exiting $?\n";
$qconfig->deleteConfigTreeRecursive('protocols bgp') || die "exiting $?\n";
@@ -1848,5 +1951,6 @@ sub main
$qconfig->setConfigTreeRecursive('protocols bgp var neighbor var address-family ipv6-unicast'
, undef, \@ordered) || die "exiting $?\n";
$qconfig->setConfigTreeRecursive('protocols bgp var neighbor var ', undef, \@ordered) || die "exiting $?\n";
+ $qconfig->setConfigTreeRecursive('protocols bgp var listen') || die "exiting $?\n";
$qconfig->setConfigTreeRecursive('protocols bgp') || die "exiting $?\n";
}
diff --git a/templates/protocols/bgp/node.tag/listen/limit/node.def b/templates/protocols/bgp/node.tag/listen/limit/node.def
new file mode 100644
index 00000000..dd249458
--- /dev/null
+++ b/templates/protocols/bgp/node.tag/listen/limit/node.def
@@ -0,0 +1,4 @@
+type: txt
+help: Maximum number of dynamic neighbors that can be created
+val_help: u32:1-5000; BGP neighbor limit
+syntax:expression: exec "${vyos_libexec_dir}/validate-value --exec \"${vyos_validators_dir}/numeric --range 1-5000\" --value \'$VAR(@)\'"; "Invalid value"
diff --git a/templates/protocols/bgp/node.tag/listen/node.def b/templates/protocols/bgp/node.tag/listen/node.def
new file mode 100644
index 00000000..5e42f6f5
--- /dev/null
+++ b/templates/protocols/bgp/node.tag/listen/node.def
@@ -0,0 +1 @@
+help: Listen for and accept BGP dynamic neighbors from range
diff --git a/templates/protocols/bgp/node.tag/listen/range/node.def b/templates/protocols/bgp/node.tag/listen/range/node.def
new file mode 100644
index 00000000..262cb77b
--- /dev/null
+++ b/templates/protocols/bgp/node.tag/listen/range/node.def
@@ -0,0 +1,7 @@
+tag:
+type: txt
+help: BGP dynamic neighbors listen range
+val_help: ipv4net; IPv4 dynamic neighbors listen range
+val_help: ipv6net; IPv6 dynamic neighbors listen range
+syntax:expression: exec "${vyos_libexec_dir}/validate-value --exec \"${vyos_validators_dir}/ipv4-prefix \" --exec \"${vyos_validators_dir}/ipv6-prefix \" --value \'$VAR(@)\'"; "Invalid value"
+commit:expression: exec "/opt/vyatta/sbin/vyatta-bgp.pl --check-bgp-listen --as $VAR(../../@)"
diff --git a/templates/protocols/bgp/node.tag/listen/range/node.tag/peer-group/node.def b/templates/protocols/bgp/node.tag/listen/range/node.tag/peer-group/node.def
new file mode 100644
index 00000000..b58d9263
--- /dev/null
+++ b/templates/protocols/bgp/node.tag/listen/range/node.tag/peer-group/node.def
@@ -0,0 +1,5 @@
+type: txt
+help: Peer group for this peer
+val_help: txt; Peer-group name
+allowed: /bin/cli-shell-api listNodes protocols bgp $VAR(../../../@) peer-group
+commit:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --exists \"protocols bgp $VAR(../../../@) peer-group $VAR(@)\" "; "protocols bgp $VAR(../../../@) peer-group $VAR(@) doesn't exist"