#
# old_revision [57521b3e79ee8b7ad948579f47416beb9e4aa380]
#
# patch "pf/bin/pfcmd_vlan"
#  from [3485461bb921e21fe8357de28eb71cd11153b272]
#    to [c1a99e7b4cbe19371362f9f9a5d7510845f8cb35]
# 
# patch "pf/lib/pf/SNMP/Cisco/Catalyst_2950.pm"
#  from [7e6f7310170570c9f69029c77949ae25a6a08a2f]
#    to [6799da435d43e4edfa33d5cdebf433a25fc76212]
#
============================================================
--- pf/bin/pfcmd_vlan	3485461bb921e21fe8357de28eb71cd11153b272
+++ pf/bin/pfcmd_vlan	c1a99e7b4cbe19371362f9f9a5d7510845f8cb35
@@ -30,6 +30,7 @@ pfcmd_vlan command [options]
    -reevaluateAccess    reevaluate the current VLAN or firewall rules of a given MAC
    -resetVlanAllPort    reset VLAN on all non-UpLink ports of the specified switch
    -resetVlanNetwork    reset VLAN on all non-UpLink ports of all managed switches
+   -runSwitchMethod     run a particular method call on a given switch (FOR ADVANCED PURPOSES)
    -setAlias            set the description of the specified switch port
    -setDefaultVlan      set the switch port to the default VLAN
    -setIfAdminStatus    set the admin status of the specified switch port
@@ -141,6 +142,7 @@ my $reevaluateAccess;
 my $deauthenticateDot1x;
 my $reAssignVlan;
 my $reevaluateAccess;
+my $runSwitchMethod;
 
 GetOptions(
     "alias:s"             => \$alias,
@@ -168,6 +170,7 @@ GetOptions(
     "reevaluateAccess"    => \$reevaluateAccess,
     "resetVlanAllPort"    => \$resetVlanAllPort,
     "resetVlanNetwork"    => \$resetVlanNetwork,
+    "runSwitchMethod"     => \$runSwitchMethod,
     "setAlias"            => \$setAlias,
     "setDefaultVlan"      => \$setDefaultVlan,
     "setIfAdminStatus"    => \$setIfAdminStatus,
@@ -228,6 +231,33 @@ if ($reevaluateAccess) {
 
     pf::enforcement::reevaluate_access( $mac, 'pfcmd_vlan' );
 
+# Warning: powerfully dangerous method below (reconsider if unstrusted users have access to pfcmd_vlan)
+# This executes a specified method call passed on the command line on a 
+# proper switch object with the parameters supplied.
+} elsif ($runSwitchMethod) {
+
+    if ( $switchDescRegExp eq '' ) {
+        pod2usage("the switch argument is necessary");
+    }
+    if ( !exists( $switchFactory->{_config}{$switchDescRegExp} ) ) {
+        pod2usage("unknown switch $switchDescRegExp");
+    }
+
+    my $switch = $switchFactory->instantiate($switchDescRegExp);
+    if (!$switch) {
+        print "Can't instantiate switch $switchDescRegExp! See log files for details\n";
+    } else {
+        # grabbing parameters
+        my ($method, @params) = @ARGV;
+        local $" = ", ";
+        $logger->debug("start handling 'runSwitchMethod' command with: ->$method(@params)");
+        {
+            no strict 'refs';
+            $switch->$method(@params);
+        }
+        $logger->debug("finished handling 'runSwitchMethod' command");
+    }
+
 } elsif ($getUpLinks) {
 
     if ( $switchDescRegExp eq '' ) {
============================================================
--- pf/lib/pf/SNMP/Cisco/Catalyst_2950.pm	7e6f7310170570c9f69029c77949ae25a6a08a2f
+++ pf/lib/pf/SNMP/Cisco/Catalyst_2950.pm	6799da435d43e4edfa33d5cdebf433a25fc76212
@@ -649,8 +649,32 @@ sub setPortSecurityMaxSecureMacAddrByIfI
    return ( defined($result) );
 }
 
-=item setPortSecurityMaxSecureMacAddrVlanByIfIndex 
+=item setPortSecurityMaxSecureMacAddrVlanAccessByIfIndex
 
+Wraps around _setPortSecurityMaxSecureMacAddrVlanAccessByIfIndex by spawning
+a process to call it thus working around bug #1369: thread crash with 
+floating network devices with VoIP through SSH transport
+
+=cut
+sub setPortSecurityMaxSecureMacAddrVlanAccessByIfIndex {
+    my ( $this, $ifIndex, $maxSecureMac ) = @_;
+    my $logger = Log::Log4perl::get_logger( ref($this) );
+
+    # we spawn a shell to workaround a thread safety bug in Net::Appliance::Session when using SSH transport
+    # http://www.cpanforum.com/threads/6909
+
+    my $command = 
+        "/usr/local/pf/bin/pfcmd_vlan -switch $this->{_ip} "
+        . "-runSwitchMethod _setPortSecurityMaxSecureMacAddrVlanAccessByIfIndex $ifIndex $maxSecureMac"
+    ;
+
+    $logger->info("spawning a pfcmd_vlan process to set 'switchport port-security maximum $maxSecureMac vlan access'");
+    pf_run($command);
+    return $TRUE;
+}
+
+=item _setPortSecurityMaxSecureMacAddrVlanByIfIndex 
+
 Sets the maximum number of MAC addresses on the data vlan for port-security on a port
 
 Warning: this method should _never_ be called in a thread. Net::Appliance::Session is not thread safe: 
@@ -660,7 +684,7 @@ Warning: this code doesn't support eleva
 Warning: this code doesn't support elevating to privileged mode. See #900 and #1370.
 
 =cut
-sub setPortSecurityMaxSecureMacAddrVlanAccessByIfIndex {
+sub _setPortSecurityMaxSecureMacAddrVlanAccessByIfIndex {
     my ( $this, $ifIndex, $maxSecureMac ) = @_;
     my $logger = Log::Log4perl::get_logger( ref($this) );
 
