From 89be0fe3dbc7dbc957bcf939d4c870881cffd795 Mon Sep 17 00:00:00 2001
From: Robert Bays <robert@vyatta.com>
Date: Thu, 2 Dec 2010 17:28:28 -0800
Subject: fix for bug 6481. change the tree walk order. add support for
 predefined order walks.

---
 lib/Vyatta/Quagga/Config.pm | 59 +++++++++++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 15 deletions(-)

(limited to 'lib')

diff --git a/lib/Vyatta/Quagga/Config.pm b/lib/Vyatta/Quagga/Config.pm
index 8afc1bed..1730f4e1 100644
--- a/lib/Vyatta/Quagga/Config.pm
+++ b/lib/Vyatta/Quagga/Config.pm
@@ -95,26 +95,26 @@ sub returnQuaggaCommands {
 
 # methods to send the commands to Quagga
 sub setConfigTree {
-  my ($self, $level, @skip_list) = @_;
-  if (_setConfigTree($level, 0, 0, @skip_list)) { return 1; }
+  my ($self, $level, $skip_list, $ordered_list) = @_;
+  if (_setConfigTree($level, 0, 0, $skip_list, $ordered_list)) { return 1; }
   return 0;
 }
 
 sub setConfigTreeRecursive {
-  my ($self, $level, @skip_list) = @_;
-  if (_setConfigTree($level, 0, 1, @skip_list)) { return 1; }
+  my ($self, $level, $skip_list, $ordered_list) = @_;
+  if (_setConfigTree($level, 0, 1, $skip_list, $ordered_list)) { return 1; }
   return 0;
 }
 
 sub deleteConfigTree {
-  my ($self, $level, @skip_list) = @_;
-  if (_setConfigTree($level, 1, 0, @skip_list)) { return 1; }
+  my ($self, $level, $skip_list, $ordered_list) = @_;
+  if (_setConfigTree($level, 1, 0, $skip_list, $ordered_list)) { return 1; }
   return 0;
 }
 
 sub deleteConfigTreeRecursive {
-  my ($self, $level, @skip_list) = @_;
-  if (_setConfigTree($level, 1, 1, @skip_list)) { return 1; }
+  my ($self, $level, $skip_list, $ordered_list) = @_;
+  if (_setConfigTree($level, 1, 1, $skip_list, $ordered_list)) { return 1; }
   return 0;
 }
 
@@ -132,8 +132,14 @@ sub deleteConfigTreeRecursive {
 #        $4 - arrays of strings to skip 
 # output: none, return failure if needed
 sub _setConfigTree {
-  my ($level, $delete, $recurse, @skip_list) = @_;
+  my ($level, $delete, $recurse, $skip, $ordered) = @_;
   my $qcom = $_qcomref;
+  my @com_array = ();
+  my @skip_list = ();
+  my @ordered_list = ();
+
+  if (defined $skip) { @skip_list = @$skip; }
+  if (defined $ordered) { @ordered_list = @$ordered; }
 
   if ((! defined $level)   ||
       (! defined $delete)  ||
@@ -156,11 +162,11 @@ sub _setConfigTree {
     print "\n";
   }
 
-  # This loop walks the list of commands and sends to quagga if appropriate
-  foreach my $key (sort $sortfunc keys %$vtyshref) {
+  # This loop walks the arrays of quagga commands and builds list to send to quagga
+  foreach my $key (keys %$vtyshref) {
     if ($_DEBUG >= 3) { print "DEBUG: _setConfigTree - key $key\n"; }
 
-    # skip parameters in skip_list
+    # skip parameters listed in skip_list
     my $found = 0;
     if ((scalar @skip_list) > 0) {
       foreach my $node (@skip_list) {
@@ -180,12 +186,12 @@ sub _setConfigTree {
          (($qcom->{$key}->{'noerr'} eq "set") && (!$delete)))) { $noerr = 1; }
 
     # this conditional matches key to level exactly or if recurse, start of key to level
-    if ((($recurse)   && ($key =~ /^$level/)) || ((! $recurse) && ($key =~ /^$level$/))) {
+    if ((($recurse) && ($key =~ /^$level/)) || ((! $recurse) && ($key =~ /^$level$/))) {
       my $index = 0;
       foreach my $cmd (@{$vtyshref->{$key}}) {
         if ($_DEBUG >= 2) { print "DEBUG: _setConfigTree - key: $key \t cmd: $cmd\n"; }
-
-        if (! _sendQuaggaCommand("$cmd", "$noerr")) { return 0; }
+        
+        push @com_array, "$cmd  !!??  $noerr";
         # remove this command so we don't hit it again in another Recurse call
         delete ${$vtyshref->{$key}}[$index];
         $index++;
@@ -193,6 +199,29 @@ sub _setConfigTree {
     }
   }
 
+  # Now let's sort based on ordered_list
+  my $index = 0;
+  while (scalar @ordered_list > 0) {
+    my $prio = shift @ordered_list;
+    my $str = sprintf "%5d", $index;
+    foreach my $line (@com_array) {
+      # add sorting order meta-data to list
+      $line =~ s/$prio/$str\:::$prio/;
+    }
+    $index++;
+  }
+
+  # and now send the commands to quagga
+  foreach my $line (sort $sortfunc @com_array) {
+    my ($command, $noerr);
+
+    # remove the ordered_list sorting meta-data
+    $line =~ s/\s+\d+:::/ /;
+    # split for our noeer info
+    ($command, $noerr) = split /  !!\?\?  /, $line;
+    if (! _sendQuaggaCommand("$command", "$noerr")) { return 0; }
+  }
+
   return 1;
 }
 
-- 
cgit v1.2.3


From 40bc37ab4e59a0cab59a6817aeedf86a759cb183 Mon Sep 17 00:00:00 2001
From: Robert Bays <robert@vyatta.com>
Date: Fri, 3 Dec 2010 17:19:47 -0800
Subject: fix ordering for non-consistent commands

---
 lib/Vyatta/Quagga/Config.pm | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'lib')

diff --git a/lib/Vyatta/Quagga/Config.pm b/lib/Vyatta/Quagga/Config.pm
index 1730f4e1..9b743502 100644
--- a/lib/Vyatta/Quagga/Config.pm
+++ b/lib/Vyatta/Quagga/Config.pm
@@ -213,12 +213,14 @@ sub _setConfigTree {
 
   # and now send the commands to quagga
   foreach my $line (sort $sortfunc @com_array) {
-    my ($command, $noerr);
+    my ($order, $command, $noerr);
 
     # remove the ordered_list sorting meta-data
     $line =~ s/\s+\d+:::/ /;
+    # remove the sort order prepend
+    ($order, $command) = split /  !!!\?\?\?  /, $line;
     # split for our noeer info
-    ($command, $noerr) = split /  !!\?\?  /, $line;
+    ($command, $noerr) = split /  !!\?\?  /, $command;
     if (! _sendQuaggaCommand("$command", "$noerr")) { return 0; }
   }
 
@@ -454,7 +456,7 @@ sub _qtree {
           if (defined $vals[0]) {
             foreach my $val (@vals) {
               my $var = _qVarReplace("$level $node $val", $qcom->{$qcommand}->{$action});
-              push @{$vtysh->{"$qcommand"}}, $var;
+              push @{$vtysh->{"$qcommand"}}, "$level $node $val  !!!???  $var";
               if ($_DEBUG) {
                 print "DEBUG: _qtree leaf node command: set $level $action $node $val \n\t\t\t\t\t$var\n";
               }
@@ -463,7 +465,7 @@ sub _qtree {
 
           else {
             my $var = _qVarReplace("$level $node", $qcom->{$qcommand}->{$action});
-            push @{$vtysh->{"$qcommand"}}, $var;
+            push @{$vtysh->{"$qcommand"}}, "$level $node  !!!???  $var";
             if ($_DEBUG) {
               print "DEBUG: _qtree node command: set $level $action $node \n\t\t\t\t$var\n";
             }
-- 
cgit v1.2.3


From 89db06448cecd96c9c2d989f4a5ceb6422bbc5fa Mon Sep 17 00:00:00 2001
From: Robert Bays <robert@vyatta.com>
Date: Fri, 3 Dec 2010 17:55:58 -0800
Subject: add debug function to clean up code

---
 lib/Vyatta/Quagga/Config.pm | 58 ++++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 29 deletions(-)

(limited to 'lib')

diff --git a/lib/Vyatta/Quagga/Config.pm b/lib/Vyatta/Quagga/Config.pm
index 9b743502..ffc861d6 100644
--- a/lib/Vyatta/Quagga/Config.pm
+++ b/lib/Vyatta/Quagga/Config.pm
@@ -63,6 +63,10 @@ sub setDebugLevel {
   return 0;
 }
 
+sub returnDebugLevel {
+  return $_DEBUG;
+}
+
 # reinitialize the vtysh hashes for troublshooting tree
 # walk post object creation
 sub _reInitialize {
@@ -120,6 +124,14 @@ sub deleteConfigTreeRecursive {
 
 ### End Public methods -
 ### Private methods
+sub _pdebug {
+  my ($level, $msg) = @_;
+
+  if (! defined $level) { return 0; }
+  if ($_DEBUG >= $level) { print "DEBUG: $msg\n"; }
+  return 1;
+}
+
 # traverse the set/delete trees and send commands to quagga
 # set traverses from $level in tree top down.  
 # delete traverses from bottom up in tree to $level.
@@ -156,15 +168,11 @@ sub _setConfigTree {
     $sortfunc = \&cmpb;
   }
 
-  if ($_DEBUG >= 3) { 
-    print "DEBUG: _setConfigTree - enter - level: $level\tdelete: $delete\trecurse: $recurse\tskip: "; 
-    foreach my $key (@skip_list) { print "$key "; }
-    print "\n";
-  }
+  _pdebug(3, "_setConfigTree - enter - level: $level\tdelete: $delete\trecurse: $recurse\tskip: @skip_list\tordered_list\t@ordered_list");
 
   # This loop walks the arrays of quagga commands and builds list to send to quagga
   foreach my $key (keys %$vtyshref) {
-    if ($_DEBUG >= 3) { print "DEBUG: _setConfigTree - key $key\n"; }
+    _pdebug(3, "_setConfigTree - key $key");
 
     # skip parameters listed in skip_list
     my $found = 0;
@@ -172,7 +180,7 @@ sub _setConfigTree {
       foreach my $node (@skip_list) {
         if ($key =~ /$node/) { 
           $found = 1; 
-          if ($_DEBUG >= 3) { print "DEBUG: _setConfigTree - key $node in skip list\n"; }
+          _pdebug(3, "_setConfigTree - key $node in skip list"); 
         }
       }
     }
@@ -189,7 +197,7 @@ sub _setConfigTree {
     if ((($recurse) && ($key =~ /^$level/)) || ((! $recurse) && ($key =~ /^$level$/))) {
       my $index = 0;
       foreach my $cmd (@{$vtyshref->{$key}}) {
-        if ($_DEBUG >= 2) { print "DEBUG: _setConfigTree - key: $key \t cmd: $cmd\n"; }
+        _pdebug(2, "_setConfigTree - key: $key \t cmd: $cmd");
         
         push @com_array, "$cmd  !!??  $noerr";
         # remove this command so we don't hit it again in another Recurse call
@@ -240,7 +248,7 @@ sub _sendQuaggaCommand {
   
   my @arg_array = ("$_vtyshexe");
   if ($noerr) { push (@arg_array, '--noerr'); }
-  if ($_DEBUG >= 2) { push (@arg_array, '-E'); }
+  if (returnDebugLevel() >= 2) { push (@arg_array, '-E'); }
   push (@arg_array, '-c');
   push (@arg_array, 'configure terminal');
 
@@ -265,7 +273,7 @@ sub _logger {
 
   push (@logger_cmd, "-i");
   push (@logger_cmd, "-t vyatta-cfg-quagga");
-  if ($_DEBUG) { push (@logger_cmd, "-s"); }
+  if (returnDebugLevel() > 0) { push (@logger_cmd, "-s"); }
   push (@logger_cmd, "@{$error_array} failed: $?");
 
   system(@logger_cmd) == 0 or die "unable to log system error message.";
@@ -282,10 +290,8 @@ sub _qVarReplace {
   my $node = shift;
   my $qcommand = shift;
 
-  if ($_DEBUG >= 2) {
-    print "DEBUG: _qVarReplace entry: node - $node\n";
-    print "DEBUG: _qVarReplace entry: qcommand - $qcommand\n";
-  }
+  _pdebug(2, "_qVarReplace entry: node - $node\n_qVarReplace entry: qcommand - $qcommand");
+
   my @nodes = split /\s/, $node;
   my @qcommands = split /\s/, $qcommand;
 
@@ -324,9 +330,7 @@ sub _qVarReplace {
 
   # remove leading space characters
   $result =~ s/^\s(.+)/$1/;
-  if ($_DEBUG >= 2) {
-    print "DEBUG: _qVarReplace exit: result - $result\n";
-  }
+  _pdebug(2, "_qVarReplace exit: result - $result");
 
   return $result;
 }
@@ -409,12 +413,12 @@ sub _qtree {
 
   } ## end else {
 
-  if ($_DEBUG) { print "DEBUG: _qtree - action: $action\tlevel: $level\n"; }
+  _pdebug(1, "_qtree - action: $action\tlevel: $level");
 
   # traverse the Vyatta config tree and translate to Quagga commands where apropos
   if (@nodes > 0) {
     foreach my $node (@nodes) {
-      if ($_DEBUG >= 2) { print "DEBUG: _qtree - foreach node loop - node $node\n"; }
+      _pdebug(2, "_qtree - foreach node loop - node $node");
 
       # for set action, need to check that the node was actually changed.  Otherwise
       # we end up re-writing every node to Quagga every commit, which is bad. Mmm' ok?
@@ -432,22 +436,22 @@ sub _qtree {
           if ($action eq 'set') {
             my $tmplhash = $config->parseTmplAll($node);
             if ($tmplhash->{'multi'}) {
-              if ($_DEBUG > 2) { print "DEBUG: multi\n"; }
+              _pdebug(2, "multi");
               @vals = $config->returnValues($node);
             }
             else {
-              if ($_DEBUG > 2) { print "DEBUG: not a multi\n"; }
+              _pdebug(2, "not a multi");
               $vals[0] = $config->returnValue($node);
             }
           }
           else {
             my $tmplhash = $config->parseTmplAll($node);
             if ($tmplhash->{'multi'}) {
-              if ($_DEBUG > 2) { print "DEBUG: multi\n"; }
+              _pdebug(2, "multi"); 
               @vals = $config->returnOrigValues($node);
             }
             else {
-              if ($_DEBUG > 2) { print "DEBUG: not a multi\n"; }
+              _pdebug(2, "not a multi");
               $vals[0] = $config->returnOrigValue($node);
             }
           }
@@ -457,18 +461,14 @@ sub _qtree {
             foreach my $val (@vals) {
               my $var = _qVarReplace("$level $node $val", $qcom->{$qcommand}->{$action});
               push @{$vtysh->{"$qcommand"}}, "$level $node $val  !!!???  $var";
-              if ($_DEBUG) {
-                print "DEBUG: _qtree leaf node command: set $level $action $node $val \n\t\t\t\t\t$var\n";
-              }
+              _pdebug(1, "_qtree leaf node command: set $level $action $node $val \n\t\t\t\t\t$var");
             }
           }
 
           else {
             my $var = _qVarReplace("$level $node", $qcom->{$qcommand}->{$action});
             push @{$vtysh->{"$qcommand"}}, "$level $node  !!!???  $var";
-            if ($_DEBUG) {
-              print "DEBUG: _qtree node command: set $level $action $node \n\t\t\t\t$var\n";
-            }
+            _pdebug(1, "_qtree node command: set $level $action $node \n\t\t\t\t$var");
           }
         }
       }
-- 
cgit v1.2.3


From ddd1d2725242e03967697ac74575a31f5608d260 Mon Sep 17 00:00:00 2001
From: Robert Bays <robert@vyatta.com>
Date: Sat, 4 Dec 2010 17:40:57 -0800
Subject: clean up code

---
 lib/Vyatta/Quagga/Config.pm | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

(limited to 'lib')

diff --git a/lib/Vyatta/Quagga/Config.pm b/lib/Vyatta/Quagga/Config.pm
index ffc861d6..1177f97d 100644
--- a/lib/Vyatta/Quagga/Config.pm
+++ b/lib/Vyatta/Quagga/Config.pm
@@ -82,7 +82,7 @@ sub _reInitialize {
 sub returnQuaggaCommands {
   my ($self, $arrayref) = @_; 
 
-  foreach my $key (sort { $b cmp $a } keys %_vtyshdel) {
+  foreach my $key (reverse sort keys %_vtyshdel) {
     foreach my $string (@{$_vtyshdel{$key}}) {
       push @{$arrayref}, "$string";
     }
@@ -141,7 +141,8 @@ sub _pdebug {
 # input: $1 - level of the tree to start at
 #        $2 - delete bool
 #        $3 - recursive bool
-#        $4 - arrays of strings to skip 
+#        $4 - array of strings to skip 
+#        $5 - array of strings to order the input to quagga
 # output: none, return failure if needed
 sub _setConfigTree {
   my ($level, $delete, $recurse, $skip, $ordered) = @_;
@@ -168,7 +169,7 @@ sub _setConfigTree {
     $sortfunc = \&cmpb;
   }
 
-  _pdebug(3, "_setConfigTree - enter - level: $level\tdelete: $delete\trecurse: $recurse\tskip: @skip_list\tordered_list\t@ordered_list");
+  _pdebug(3, "_setConfigTree - enter - level: $level\tdelete: $delete\trecurse: $recurse\tskip: @skip_list\tordered_list: @ordered_list");
 
   # This loop walks the arrays of quagga commands and builds list to send to quagga
   foreach my $key (keys %$vtyshref) {
@@ -199,7 +200,7 @@ sub _setConfigTree {
       foreach my $cmd (@{$vtyshref->{$key}}) {
         _pdebug(2, "_setConfigTree - key: $key \t cmd: $cmd");
         
-        push @com_array, "$cmd  !!??  $noerr";
+        push @com_array, "$cmd  \036  $noerr";
         # remove this command so we don't hit it again in another Recurse call
         delete ${$vtyshref->{$key}}[$index];
         $index++;
@@ -225,10 +226,8 @@ sub _setConfigTree {
 
     # remove the ordered_list sorting meta-data
     $line =~ s/\s+\d+:::/ /;
-    # remove the sort order prepend
-    ($order, $command) = split /  !!!\?\?\?  /, $line;
-    # split for our noeer info
-    ($command, $noerr) = split /  !!\?\?  /, $command;
+    # split our commands into individual components
+    ($order, $command, $noerr) = split /  \036  /, $line;
     if (! _sendQuaggaCommand("$command", "$noerr")) { return 0; }
   }
 
@@ -460,14 +459,14 @@ sub _qtree {
           if (defined $vals[0]) {
             foreach my $val (@vals) {
               my $var = _qVarReplace("$level $node $val", $qcom->{$qcommand}->{$action});
-              push @{$vtysh->{"$qcommand"}}, "$level $node $val  !!!???  $var";
+              push @{$vtysh->{"$qcommand"}}, "$level $node $val  \036  $var";
               _pdebug(1, "_qtree leaf node command: set $level $action $node $val \n\t\t\t\t\t$var");
             }
           }
 
           else {
             my $var = _qVarReplace("$level $node", $qcom->{$qcommand}->{$action});
-            push @{$vtysh->{"$qcommand"}}, "$level $node  !!!???  $var";
+            push @{$vtysh->{"$qcommand"}}, "$level $node  \036  $var";
             _pdebug(1, "_qtree node command: set $level $action $node \n\t\t\t\t$var");
           }
         }
-- 
cgit v1.2.3