mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 12:52:37 +00:00 
			
		
		
		
	git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15276 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			1124 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1124 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head1
 | 
						|
  xCAT plugin package to handle xdsh
 | 
						|
 | 
						|
   Supported command:
 | 
						|
         nodenetconn
 | 
						|
         ipforward (internal command)
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
package xCAT_plugin::route;
 | 
						|
BEGIN
 | 
						|
{
 | 
						|
  $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | 
						|
}
 | 
						|
use lib "$::XCATROOT/lib/perl";
 | 
						|
use strict;
 | 
						|
use xCAT::Table;
 | 
						|
use xCAT::Utils;
 | 
						|
use xCAT::TableUtils;
 | 
						|
use xCAT::ServiceNodeUtils;
 | 
						|
use xCAT::NetworkUtils;
 | 
						|
use xCAT::MsgUtils;
 | 
						|
use Getopt::Long;
 | 
						|
use xCAT::NodeRange;
 | 
						|
use Data::Dumper;
 | 
						|
use xCAT::NodeRange;
 | 
						|
use IO::File;
 | 
						|
use File::Copy;
 | 
						|
use Sys::Hostname;
 | 
						|
 | 
						|
 | 
						|
my $xcat_config_start="# xCAT_CONFIG_START";
 | 
						|
my $xcat_config_end="# xCAT_CONFIG_END";
 | 
						|
 | 
						|
 | 
						|
 | 
						|
1;
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  handled_commands
 | 
						|
 | 
						|
Return list of commands handled by this plugin
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
sub handled_commands
 | 
						|
{
 | 
						|
    return {
 | 
						|
            makeroutes => "route",
 | 
						|
            ipforward => "route"
 | 
						|
           };
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  preprocess_request
 | 
						|
 | 
						|
  Preprocess the command
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub preprocess_request
 | 
						|
{
 | 
						|
    my $request  = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $sub_req  = shift;
 | 
						|
    my $command = $request->{command}->[0];
 | 
						|
    my $args    = $request->{arg};
 | 
						|
 | 
						|
    #if already preprocessed, go straight to request
 | 
						|
    if ((defined($request->{_xcatpreprocessed}))
 | 
						|
        && ($request->{_xcatpreprocessed}->[0] == 1))
 | 
						|
    {
 | 
						|
        return [$request];
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    if ($command eq "ipforward") {
 | 
						|
        my $nodes=$request->{node};
 | 
						|
	my @sns=();
 | 
						|
	if ($nodes) {
 | 
						|
	    @sns=@$nodes;
 | 
						|
	}
 | 
						|
	#print "sns=@sns\n";
 | 
						|
	my @requests=();
 | 
						|
	foreach (@sns) {
 | 
						|
	    my $reqcopy = {%$request};
 | 
						|
	    $reqcopy->{'node'}=[];
 | 
						|
	    $reqcopy->{'_xcatdest'}=$_;
 | 
						|
	    $reqcopy->{_xcatpreprocessed}->[0] = 1;
 | 
						|
	    push @requests, $reqcopy;
 | 
						|
	}
 | 
						|
	return \@requests;
 | 
						|
    } else {
 | 
						|
	# parse the options
 | 
						|
	@ARGV=();
 | 
						|
	if ($args) {
 | 
						|
	    @ARGV=@{$args};
 | 
						|
	}
 | 
						|
	Getopt::Long::Configure("bundling");
 | 
						|
	Getopt::Long::Configure("no_pass_through");
 | 
						|
	
 | 
						|
	my $routelist_in;
 | 
						|
	my $delete=0;
 | 
						|
	if(!GetOptions(
 | 
						|
		'h|help'     => \$::HELP,
 | 
						|
		'v|version'  => \$::VERSION,
 | 
						|
		'r|routename=s'  => \$routelist_in,
 | 
						|
		'd|delete'  => \$delete,
 | 
						|
	   ))
 | 
						|
	{
 | 
						|
	    &usage($callback);
 | 
						|
	    return 1;
 | 
						|
	}
 | 
						|
	
 | 
						|
	# display the usage if -h or --help is specified
 | 
						|
	if ($::HELP) {
 | 
						|
	    &usage($callback);
 | 
						|
	    return 0;
 | 
						|
	}
 | 
						|
	
 | 
						|
	
 | 
						|
	# display the version statement if -v or --verison is specified
 | 
						|
	if ($::VERSION)
 | 
						|
	{
 | 
						|
	    my $rsp={};
 | 
						|
	    $rsp->{data}->[0]= xCAT::Utils->Version();
 | 
						|
	    $callback->($rsp);
 | 
						|
	    return 0;
 | 
						|
	}
 | 
						|
 | 
						|
        #make sure the input routes are in the routes table.
 | 
						|
	if ($routelist_in) {
 | 
						|
	    my %all_routes=();
 | 
						|
	    my $routestab=xCAT::Table->new("routes", -create =>1);
 | 
						|
	    if ($routestab) {
 | 
						|
		my @tmp1=$routestab->getAllAttribs(('routename', 'net'));
 | 
						|
		if (@tmp1 > 0) {
 | 
						|
		    foreach(@tmp1) {
 | 
						|
			$all_routes{$_->{routename}} = $_;
 | 
						|
			$_->{process} = 0;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    
 | 
						|
	    my @badroutes=();
 | 
						|
	    foreach(split(',', $routelist_in)) {
 | 
						|
		if (!exists($all_routes{$_})) {
 | 
						|
		    push(@badroutes, $_);
 | 
						|
		} 
 | 
						|
	    }
 | 
						|
	    if (@badroutes>0) {
 | 
						|
		my $rsp={};
 | 
						|
		my $badroutes_s=join(',', @badroutes);
 | 
						|
		if (@badroutes==1) {
 | 
						|
		    $rsp->{error}->[0]= "The route $badroutes_s is not defined in the routes table.";
 | 
						|
		} else {
 | 
						|
		    $rsp->{error}->[0]= "The routes $badroutes_s are not defined in the routes table.";
 | 
						|
		}
 | 
						|
		$callback->($rsp);
 | 
						|
		return 1;
 | 
						|
	    }
 | 
						|
	} 
 | 
						|
 | 
						|
	if (@ARGV == 0) { #no noderange is specifiled, assume it is on the mn
 | 
						|
	    my $reqcopy = {%$request};
 | 
						|
	    $reqcopy->{_xcatpreprocessed}->[0] = 1;
 | 
						|
	    if ($routelist_in) {
 | 
						|
		$reqcopy->{routelist}->[0]=$routelist_in;
 | 
						|
	    }
 | 
						|
	    if ($delete) {
 | 
						|
		$reqcopy->{delete}->[0]=1;
 | 
						|
	    }
 | 
						|
	    return [$reqcopy];
 | 
						|
	} else { #noderange is specified, 
 | 
						|
	    my $ret=[];
 | 
						|
	    my $nr=$ARGV[0];
 | 
						|
	    my @noderange = xCAT::NodeRange::noderange($nr, 1);
 | 
						|
	    my @missednodes=xCAT::NodeRange::nodesmissed();
 | 
						|
	    if (@missednodes > 0) {
 | 
						|
		my $rsp={};
 | 
						|
		$rsp->{error}->[0]= "Invalide nodes in noderange: " . join(',', @missednodes);
 | 
						|
		$callback->($rsp);
 | 
						|
		return 1;
 | 
						|
	    }
 | 
						|
	    my @servicenodes=xCAT::ServiceNodeUtils->getSNList();
 | 
						|
 | 
						|
            #print "noderange=@noderange, missednodes=@missednodes, servicenodes=@servicenodes\n"; 
 | 
						|
 | 
						|
	    #pick out the service nodes from the node list
 | 
						|
	    foreach my $sn (@servicenodes) {
 | 
						|
		if (grep /^$sn$/, @noderange) {
 | 
						|
		    @noderange=grep(!/^$sn$/, @noderange);
 | 
						|
		    my $reqcopy = {%$request};
 | 
						|
		    $reqcopy->{_xcatpreprocessed}->[0] = 1;
 | 
						|
		    $reqcopy->{'_xcatdest'}	= $sn;	
 | 
						|
		    $reqcopy->{node} = [$sn];
 | 
						|
		    if ($routelist_in) {
 | 
						|
			$reqcopy->{routelist}->[0]=$routelist_in;
 | 
						|
		    }
 | 
						|
		    if ($delete) {
 | 
						|
			$reqcopy->{delete}->[0]=1;
 | 
						|
		    }
 | 
						|
		    push(@$ret, $reqcopy);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
      
 | 
						|
            #now find out the service nodes for each node and 
 | 
						|
            #send the request to the service node
 | 
						|
	    my $sn_hash = xCAT::ServiceNodeUtils->get_ServiceNode(\@noderange, "xcat", "MN");
 | 
						|
    
 | 
						|
	    # build each request for each service node
 | 
						|
	    foreach my $sn (keys %$sn_hash)
 | 
						|
	    {
 | 
						|
		my $reqcopy = {%$request};
 | 
						|
		$reqcopy->{node} = $sn_hash->{$sn};
 | 
						|
		$reqcopy->{'_xcatdest'} = $sn;
 | 
						|
		$reqcopy->{_xcatpreprocessed}->[0] = 1;
 | 
						|
		$reqcopy->{remote}->[0] = 1;
 | 
						|
		if ($routelist_in) {
 | 
						|
		    $reqcopy->{routelist}->[0]=$routelist_in;
 | 
						|
		}
 | 
						|
		if ($delete) {
 | 
						|
		    $reqcopy->{delete}->[0]=1;
 | 
						|
		}
 | 
						|
		push(@$ret, $reqcopy);
 | 
						|
	    }
 | 
						|
 | 
						|
	    return $ret;
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  process_request
 | 
						|
 | 
						|
  Process the command
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub process_request
 | 
						|
{
 | 
						|
 | 
						|
    my $request  = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $sub_req  = shift;
 | 
						|
    my $command = $request->{command}->[0];
 | 
						|
 | 
						|
    if ($command eq "makeroutes") {
 | 
						|
	return process_makeroutes($request, $callback, $sub_req);
 | 
						|
    } elsif ($command eq "ipforward") {
 | 
						|
	return process_ipforward($request, $callback, $sub_req);
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
sub process_makeroutes {
 | 
						|
    my $request  = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $sub_req  = shift;
 | 
						|
    my $command = $request->{command}->[0];
 | 
						|
 | 
						|
    my $nodes;
 | 
						|
    if (exists($request->{node})) {
 | 
						|
	$nodes=$request->{node};
 | 
						|
    }
 | 
						|
 | 
						|
    my $delete=0;
 | 
						|
    if (exists($request->{delete})) {
 | 
						|
	$delete=$request->{delete}->[0];
 | 
						|
    }
 | 
						|
 | 
						|
    my $remote=0;
 | 
						|
    if (exists($request->{remote})) {
 | 
						|
	$remote=$request->{remote}->[0];
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    my $routelist;
 | 
						|
    if (exists($request->{routelist})) {
 | 
						|
	$routelist=$request->{routelist}->[0];
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    #get all the routes from the routes table
 | 
						|
    my %all_routes=();
 | 
						|
    my $routestab=xCAT::Table->new("routes", -create =>1);
 | 
						|
    if ($routestab) {
 | 
						|
	my @tmp1=$routestab->getAllAttribs(('routename', 'net', 'mask', 'gateway', 'ifname'));
 | 
						|
	if (@tmp1 > 0) {
 | 
						|
	    foreach(@tmp1) {
 | 
						|
		$all_routes{$_->{routename}} = $_;
 | 
						|
		$_->{process} = 0;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    
 | 
						|
    if ($routelist) {
 | 
						|
	foreach(split(',', $routelist)) {
 | 
						|
	    $all_routes{$_}->{process}=1;
 | 
						|
	    if (($nodes) && ($remote)) {
 | 
						|
		$all_routes{$_}->{nodes}=$nodes;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    } else {
 | 
						|
	#get the routes for each nodes from the noderes table (for sn and cn) and site table (for mn)
 | 
						|
	if ($nodes) {
 | 
						|
	    my $nrtab=xCAT::Table->new("noderes", -create =>1);
 | 
						|
	    my $nrhash = $nrtab->getNodesAttribs($nodes, ['routenames']) ;
 | 
						|
	    foreach(@$nodes) {
 | 
						|
		my @badroutes=();
 | 
						|
		my $node=$_;
 | 
						|
		my $rn;
 | 
						|
		my $ent=$nrhash->{$node}->[0];
 | 
						|
		if (ref($ent) and defined $ent->{routenames}) {
 | 
						|
		    $rn = $ent->{routenames};
 | 
						|
		}
 | 
						|
		if ($rn) {
 | 
						|
		    my @a=split(',', $rn);
 | 
						|
		    my @badroutes=();
 | 
						|
		    foreach my $r (@a) {
 | 
						|
			if (! exists($all_routes{$r})) {
 | 
						|
			    push(@badroutes, $r);
 | 
						|
			} else {
 | 
						|
			    #print "got here...., remote=$remote\n";
 | 
						|
			    $all_routes{$r}->{process}=1;
 | 
						|
			    if ($remote) {
 | 
						|
				my $pa=$all_routes{$r}->{nodes};
 | 
						|
				if ($pa) {
 | 
						|
				    push(@$pa, $node);
 | 
						|
				} else {
 | 
						|
				    $all_routes{$r}->{nodes}=[$node];
 | 
						|
				}
 | 
						|
			    }
 | 
						|
			}
 | 
						|
		    }
 | 
						|
		    if (@badroutes > 0) {
 | 
						|
			my $badroutes_s=join(',', @badroutes);
 | 
						|
			my $rsp={};
 | 
						|
			if (@badroutes==1) {
 | 
						|
			    $rsp->{error}->[0]= "The route $badroutes_s is not defined in the routes table. Please check noderes.routenames for node $node.";
 | 
						|
			} else {
 | 
						|
			    $rsp->{error}->[0]= "The routes $badroutes_s are not defined in the routes table. Please check noderes.routenames for node $node.";
 | 
						|
			}
 | 
						|
			$callback->($rsp);
 | 
						|
			return 1;
 | 
						|
		    }
 | 
						|
		} else {
 | 
						|
		    my $rsp={};
 | 
						|
		    $rsp->{data}->[0]= "No routes defined in noderes.routenames for node $node, skiping $node.";
 | 
						|
		    $callback->($rsp);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else { #this is mn, get the routes from the site table
 | 
						|
	    my @mnroutes = xCAT::TableUtils->get_site_attribute("mnroutenames");
 | 
						|
	    if ($mnroutes[0]) {
 | 
						|
		my @a=split(',', $mnroutes[0]);
 | 
						|
		my @badroutes=();
 | 
						|
		foreach my $r (@a) {
 | 
						|
		    if (! exists($all_routes{$r})) {
 | 
						|
			push(@badroutes, $r);
 | 
						|
		    } else {
 | 
						|
			$all_routes{$r}->{process}=1;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
		if (@badroutes > 0) {
 | 
						|
		    my $badroutes_s=join(',', @badroutes);
 | 
						|
		    my $rsp={};
 | 
						|
		    if (@badroutes==1) {
 | 
						|
			$rsp->{error}->[0]= "The route $badroutes_s is not defined in the routes table. Please check site.mnroutenames for the management node.";
 | 
						|
		    } else {
 | 
						|
			$rsp->{error}->[0]= "The routes $badroutes_s are not defined in the routes table. Please check site.mnroutenames for the management node.";
 | 
						|
		    }
 | 
						|
		    $callback->($rsp);
 | 
						|
		    return 1;
 | 
						|
		}
 | 
						|
	    } else {
 | 
						|
		my $rsp={};
 | 
						|
		$rsp->{data}->[0]= "No routes defined in the site.mnroutenames for the management node.";
 | 
						|
		$callback->($rsp);
 | 
						|
		return 1;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    #print Dumper(%all_routes); 
 | 
						|
 | 
						|
    #now let's handle the route creatation and deletion
 | 
						|
    my @sns=(); 
 | 
						|
    my $installdir = xCAT::TableUtils->getInstallDir();
 | 
						|
    while (my ($routename, $route_hash) = each(%all_routes)) {
 | 
						|
	if ($route_hash->{process}) {
 | 
						|
	    my ($gw_name, $gw_ip)=xCAT::NetworkUtils->gethostnameandip($route_hash->{gateway});
 | 
						|
	    push(@sns, $gw_name);
 | 
						|
 | 
						|
        if ($route_hash->{net} =~ /:/) {
 | 
						|
            # Remove the subnet postfix like /64
 | 
						|
            if ($route_hash->{net} =~ /\//) {
 | 
						|
                $route_hash->{net} =~ s/\/.*$//;
 | 
						|
            }
 | 
						|
            # Remove the "/" from the ipv6 prefixlength
 | 
						|
            if ($route_hash->{mask}) {
 | 
						|
                if ($route_hash->{mask} =~ /\//) {
 | 
						|
                    $route_hash->{mask} =~ s/^\///;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
	    if ($remote) { #to the nodes
 | 
						|
		my $nodes_tmp=$route_hash->{nodes};
 | 
						|
		#print "nodes=@$nodes_tmp, remote=$remote, delete=$delete\n";
 | 
						|
		my $op="add";
 | 
						|
		if ($delete)  { $op="delete"; }
 | 
						|
		my $output = xCAT::Utils->runxcmd(
 | 
						|
		    {
 | 
						|
			command => ["xdsh"], 
 | 
						|
			node => $nodes_tmp, 
 | 
						|
			arg => ["-e", "/$installdir/postscripts/routeop $op " . $route_hash->{net} . " " . $route_hash->{mask} . " $gw_ip" . " $route_hash->{ifname}"],
 | 
						|
			_xcatpreprocessed => [1],
 | 
						|
		    }, 
 | 
						|
		    $sub_req, -1, 1);
 | 
						|
		my $rsp={};
 | 
						|
		$rsp->{data}=$output;
 | 
						|
		$callback->($rsp);
 | 
						|
	    } else { #local on mn or sn
 | 
						|
		if ($delete)  {
 | 
						|
		    delete_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name, $route_hash->{ifname});
 | 
						|
		} 
 | 
						|
		else {
 | 
						|
		    set_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name,$route_hash->{ifname});
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    
 | 
						|
 | 
						|
    #not all gateways are service nodes
 | 
						|
    my %sn_hash=();
 | 
						|
    my @allSN=xCAT::ServiceNodeUtils->getAllSN();
 | 
						|
    my %allSN_hash=();
 | 
						|
    foreach(@allSN) {$allSN_hash{$_}=1;}
 | 
						|
    foreach my $sn (@sns) {
 | 
						|
	if (exists($allSN_hash{$sn})) {
 | 
						|
	    $sn_hash{$sn}=1;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    #update servicenode.ipforward 
 | 
						|
    my $sntab=xCAT::Table->new("servicenode", -create => 1,-autocommit => 1);
 | 
						|
    my %valuehash=();
 | 
						|
    my $value=1;
 | 
						|
    if ($delete) {$value=0;}
 | 
						|
    foreach my $sn (keys %sn_hash)  {
 | 
						|
	$valuehash{$sn} = { ipforward=>$value };
 | 
						|
    }
 | 
						|
    $sntab->setNodesAttribs(\%valuehash);
 | 
						|
 | 
						|
    #go to the service nodes to enable/disable ipforwarding
 | 
						|
    my @nodes=keys(%sn_hash);
 | 
						|
    $sub_req->({
 | 
						|
	command=>['ipforward'],
 | 
						|
	node=>\@nodes,
 | 
						|
	arg=>[$delete]}, 
 | 
						|
	       $callback);
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
sub process_ipforward {
 | 
						|
    my $request  = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $sub_req  = shift;
 | 
						|
    my $args    = $request->{arg};
 | 
						|
 | 
						|
    my $delete=0;
 | 
						|
    if ($args) {
 | 
						|
	$delete = $args->[0];
 | 
						|
    }
 | 
						|
    
 | 
						|
    if ($delete) {
 | 
						|
	xCAT::NetworkUtils->setup_ip_forwarding(0);
 | 
						|
    } else {
 | 
						|
	xCAT::NetworkUtils->setup_ip_forwarding(1);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
sub usage {
 | 
						|
    my $cb=shift;
 | 
						|
    my $rsp={};
 | 
						|
 | 
						|
    $rsp->{data}->[0]= "Usage: makeroutes -h";
 | 
						|
    $rsp->{data}->[1]= "       makeroutes -v";
 | 
						|
    $rsp->{data}->[2]= "       makeroutes [-r routename[,routename...]]";
 | 
						|
    $rsp->{data}->[3]= "       makeroutes [-r routename[,routename...]] -d ";
 | 
						|
    $rsp->{data}->[4]= "       makeroutes noderange [-r routename[,routename...]]";
 | 
						|
    $rsp->{data}->[5]= "       makeroutes noderange [-r routename[,routename...]] -d";
 | 
						|
    $cb->($rsp);
 | 
						|
}
 | 
						|
 | 
						|
#check if the route exits or not from the route table
 | 
						|
sub route_exists {
 | 
						|
    my $net = shift;
 | 
						|
    my $mask = shift;
 | 
						|
    my $gw_ip = shift;
 | 
						|
    my $gw=shift;
 | 
						|
 | 
						|
    my $islinux=xCAT::Utils->isLinux();
 | 
						|
 | 
						|
    # ipv6 net
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        if ($islinux) {
 | 
						|
            my $result = `ip -6 route show $net/$mask`;
 | 
						|
            # ip -6 route show will return nothing if the route does not exist
 | 
						|
            if (!$result || ($? != 0))
 | 
						|
            {
 | 
						|
                return 0;
 | 
						|
            } else {
 | 
						|
                return 1;
 | 
						|
            }
 | 
						|
        } else { # AIX
 | 
						|
            # TODO
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
         my $result;
 | 
						|
         $result=`netstat -nr|grep $net`;
 | 
						|
         if ($? == 0) {
 | 
						|
             if ($result) {
 | 
						|
                 my @b=split('\n', $result);
 | 
						|
                 foreach my $tmp (@b) {
 | 
						|
                     chomp($tmp);
 | 
						|
                     my @a=split(' ', $tmp);
 | 
						|
                     if ($islinux) { #Linux
 | 
						|
                         if (@a >= 3) {
 | 
						|
                             my $net1=$a[0];
 | 
						|
                             my $mask1=$a[2];
 | 
						|
                             my $gw1=$a[1];
 | 
						|
                             if (($net1 eq $net) && ($mask1 eq $mask) && (($gw1 eq $gw) || ($gw1 eq $gw_ip)))  {
 | 
						|
                                 return 1;
 | 
						|
                             }
 | 
						|
                         }
 | 
						|
                     } 
 | 
						|
                     else { #AIX
 | 
						|
                         if (@a >= 2) {
 | 
						|
                             my $tmp1=$a[0];
 | 
						|
                             my $gw1=$a[1];
 | 
						|
 | 
						|
                             #now convert $mask to bits
 | 
						|
                             $net =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
 | 
						|
                             my $netnum = ($1<<24)+($2<<16)+($3<<8)+$4;
 | 
						|
                             my $bits=32;
 | 
						|
                             while (($netnum % 2) == 0) {
 | 
						|
                                 $bits--;
 | 
						|
                                 $netnum=$netnum>>1;
 | 
						|
                             }
 | 
						|
                             my $tmp2="$net/$bits";
 | 
						|
                             if (($tmp1 eq $tmp2) && (($gw1 eq $gw) || ($gw1 eq $gw_ip)))  {
 | 
						|
                                 return 1;
 | 
						|
                             }
 | 
						|
                         } # end if (@a >= 2)
 | 
						|
                     } #end else linux/aix
 | 
						|
                 } # end foreach
 | 
						|
             } # end if ($result)
 | 
						|
        } # end if ($? == 0 
 | 
						|
    } # end else ipv4/ipv6
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
# sets the route with given parameters
 | 
						|
sub set_route {
 | 
						|
    my $callback=shift;
 | 
						|
    my $net = shift;
 | 
						|
    my $mask = shift;
 | 
						|
    my $gw_ip = shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $ifname=shift;
 | 
						|
 | 
						|
    my $host=hostname();
 | 
						|
 | 
						|
    #print "set_route get called\n";
 | 
						|
 | 
						|
    my $result;
 | 
						|
    if (!route_exists($net, $mask, $gw_ip, $gw)) {
 | 
						|
	#set temporay route
 | 
						|
    my $cmd;
 | 
						|
    # ipv6 network
 | 
						|
    if ($net =~ /:/) {
 | 
						|
	    if (xCAT::Utils->isLinux()) {
 | 
						|
	        $cmd="ip -6 route add $net/$mask via $gw_ip";
 | 
						|
	    } else {
 | 
						|
            # AIX TODO
 | 
						|
	    }
 | 
						|
    } else {
 | 
						|
	    if (xCAT::Utils->isLinux()) {
 | 
						|
	        $cmd="route add -net $net netmask $mask gw $gw_ip";
 | 
						|
	    } else {
 | 
						|
	        $cmd="route add -net $net -netmask $mask $gw_ip";
 | 
						|
	    }
 | 
						|
    }    
 | 
						|
	#print "cmd=$cmd\n";
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Adding temporary route: $cmd";
 | 
						|
	$callback->($rsp);
 | 
						|
 | 
						|
	$result=`$cmd 2>&1`;
 | 
						|
	if ($? != 0) {
 | 
						|
	    my $rsp={};
 | 
						|
	    $rsp->{error}->[0]= "$host: $cmd\nerror code=$?, result=$result\n";
 | 
						|
	    $callback->($rsp);
 | 
						|
	    #return 1;
 | 
						|
	} 
 | 
						|
    } else {
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: The temporary route already exists for $net.";
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
 | 
						|
    #handle persistent routes
 | 
						|
    if (xCAT::Utils->isLinux()) { #Linux
 | 
						|
	my $os = xCAT::Utils->osver();
 | 
						|
	#print "os=$os  $net, $mask, $gw_ip, $gw, $ifname\n";
 | 
						|
	if ($os =~ /sles/) { #sles
 | 
						|
	    addPersistentRoute_Sles($callback, $net, $mask, $gw_ip, $gw, $ifname);
 | 
						|
	} elsif ($os =~ /ubuntu/) { #ubuntu or Debian?
 | 
						|
	    #my $filename="/etc/network/interfaces";
 | 
						|
	    #my @output=getConfig($filename);
 | 
						|
	    #Example:
 | 
						|
	    #auto eth0
 | 
						|
	    #iface eth0 inet static
 | 
						|
	    #	address 192.168.1.2
 | 
						|
	    #	netmask 255.255.255.0
 | 
						|
	    #	gateway 192.168.1.254
 | 
						|
	    #	up route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1
 | 
						|
	    #	down route del -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1		   
 | 
						|
	    my $rsp={};
 | 
						|
	    $rsp->{data}->[0]= "$host: Adding persistent route on Ubuntu is not supported yet.";
 | 
						|
	    $callback->($rsp);
 | 
						|
	    
 | 
						|
	}
 | 
						|
	elsif ($os =~ /rh|fedora|centos/) { #RH, Ferdora, CentOS
 | 
						|
	    addPersistentRoute_RH($callback, $net, $mask, $gw_ip, $gw, $ifname);
 | 
						|
	} 	
 | 
						|
    } else { #AIX
 | 
						|
	# chdev -l inet0 -a route=net,-hopcount,0,,0,192.168.1.1
 | 
						|
	# chdev -l inet0 -a route=net, -hopcount,255.255.255.128,,,,,192.168.3.155,192.168.2.1
 | 
						|
	# lsattr -El inet0 -a route
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Adding persistent route on AIX is not supported yet.";
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
    
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
# deletes the route with given parameters
 | 
						|
sub delete_route {
 | 
						|
    my $callback=shift;
 | 
						|
    my $net = shift;
 | 
						|
    my $mask = shift;
 | 
						|
    my $gw_ip = shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $ifname=shift;
 | 
						|
 | 
						|
    my $host=hostname();
 | 
						|
 | 
						|
    #print "delete_route get called\n";
 | 
						|
 | 
						|
    my $result;
 | 
						|
    if (route_exists($net, $mask, $gw_ip, $gw)) {
 | 
						|
	#delete  route temporarily
 | 
						|
    my $cmd;
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        if (xCAT::Utils->isLinux()) {
 | 
						|
            $cmd = "ip -6 route delete $net/$mask via $gw_ip";
 | 
						|
        } else {
 | 
						|
            # AIX TODO
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
	    if (xCAT::Utils->isLinux()) {
 | 
						|
	        $cmd="route delete -net $net netmask $mask gw $gw_ip";
 | 
						|
	    } else {
 | 
						|
	        $cmd="route delete -net $net -netmask $mask $gw_ip";
 | 
						|
	    }
 | 
						|
    }
 | 
						|
	#print "cmd=$cmd\n";
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Removing the temporary route: $cmd";
 | 
						|
	$callback->($rsp);
 | 
						|
 | 
						|
	$result=`$cmd 2>&1`;
 | 
						|
	if ($? != 0) {
 | 
						|
	    my $rsp={};
 | 
						|
	    $rsp->{error}->[0]= "$host: $cmd\nerror code=$?, result=$result\n";
 | 
						|
	    $callback->($rsp);
 | 
						|
	}
 | 
						|
    } else {
 | 
						|
	my $rsp={};
 | 
						|
    if ($net =~ /:/) {
 | 
						|
	    $rsp->{data}->[0]= "$host: The temporary route does not exist for $net/$mask.";
 | 
						|
    } else {
 | 
						|
	    $rsp->{data}->[0]= "$host: The temporary route does not exist for $net.";
 | 
						|
    }
 | 
						|
	$callback->($rsp);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    #handle persistent route
 | 
						|
    if (xCAT::Utils->isLinux()) { #Linux
 | 
						|
	my $os = xCAT::Utils->osver();
 | 
						|
	if ($os =~ /sles/) { #sles
 | 
						|
	    deletePersistentRoute_Sles($callback, $net, $mask, $gw_ip, $gw, $ifname);
 | 
						|
	} elsif ($os =~ /ubuntu/) { #ubuntu or Debian?
 | 
						|
	    #my $filename="/etc/network/interfaces";
 | 
						|
	    #my @output=getConfig($filename);
 | 
						|
	    #Example:
 | 
						|
	    #auto eth0
 | 
						|
	    #iface eth0 inet static
 | 
						|
	    #	address 192.168.1.2
 | 
						|
	    #	netmask 255.255.255.0
 | 
						|
	    #	gateway 192.168.1.254
 | 
						|
	    #	up route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1
 | 
						|
	    #	down route del -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1		   
 | 
						|
	    my $rsp={};
 | 
						|
	    $rsp->{data}->[0]= "$host: Removing persistent route on Ubuntu is not supported yet.";
 | 
						|
	    $callback->($rsp);
 | 
						|
	}
 | 
						|
	elsif ($os =~ /rh|fedora|centos/) { #RH, Ferdora 
 | 
						|
	    deletePersistentRoute_RH($callback, $net, $mask, $gw_ip, $gw, $ifname);
 | 
						|
	} 	
 | 
						|
    } else { #AIX
 | 
						|
	# chdev -l inet0 -a delroute=net,-hopcount,0,,0,192.168.1.1
 | 
						|
	# chdev -l inet0 -a delroute=net,-hopcount,255.255.255.128,,,,,192.168.3.128,192.168.2.1
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Removing persistent route on AIX is not supported yet.";
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#set the given route to the configuration file  
 | 
						|
sub setConfig {
 | 
						|
    my $filename=shift;
 | 
						|
    my $new_conf_block=shift;
 | 
						|
    #print "filename=$filename\n";
 | 
						|
 | 
						|
    my $new_config=join("\n", @$new_conf_block);
 | 
						|
    my $last_char = substr $new_config,-1,1;
 | 
						|
    if ($last_char ne "\n") { $new_config .= "\n"; }
 | 
						|
 | 
						|
    my $filename_tmp = "$filename.$$";
 | 
						|
    open (OUTFILE, '>', $filename_tmp);
 | 
						|
    my $found=0;
 | 
						|
    if (-f $filename) {
 | 
						|
	open (INFILE,  '<', $filename);
 | 
						|
	my $inblock=0;
 | 
						|
	while (<INFILE>) { 
 | 
						|
	    my $line=$_;
 | 
						|
	    if (!$inblock) {
 | 
						|
		print OUTFILE $line;
 | 
						|
	    }
 | 
						|
	    if ($line =~ /$xcat_config_start/) {
 | 
						|
		$found=1;
 | 
						|
		$inblock=1;
 | 
						|
		print OUTFILE $new_config; 
 | 
						|
	    } elsif ($line =~ /$xcat_config_end/) {
 | 
						|
		$inblock=0;
 | 
						|
		print OUTFILE "$xcat_config_end\n";
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (!$found) {
 | 
						|
	print OUTFILE "$xcat_config_start\n";
 | 
						|
	print OUTFILE $new_config;  
 | 
						|
	print OUTFILE "$xcat_config_end\n";
 | 
						|
    } 
 | 
						|
    close (INFILE);
 | 
						|
    close (OUTFILE);
 | 
						|
    copy($filename_tmp, $filename);
 | 
						|
    unlink($filename_tmp);
 | 
						|
}
 | 
						|
  
 | 
						|
#gets the xCAT configurations from the given file
 | 
						|
sub getConfig {
 | 
						|
    my $filename=shift;
 | 
						|
    my @output=();
 | 
						|
    if (-f $filename) { 
 | 
						|
	open(FILE, "<", $filename);
 | 
						|
	my $xcatconf = 0;
 | 
						|
	my $first=0;
 | 
						|
	while (<FILE>) {
 | 
						|
	    chomp;
 | 
						|
	    if (/$xcat_config_start/) {
 | 
						|
		$xcatconf = 1;
 | 
						|
		$first=1;
 | 
						|
	    }
 | 
						|
	    elsif (/$xcat_config_end/) {
 | 
						|
		$xcatconf = 0;
 | 
						|
	    }
 | 
						|
	    if ($first) {
 | 
						|
		$first=0;
 | 
						|
		next;
 | 
						|
	    }
 | 
						|
	    
 | 
						|
	    if ($xcatconf) {
 | 
						|
		push @output, $_;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return @output;
 | 
						|
}
 | 
						|
 | 
						|
#add the routes to the /etc/sysconfig/network/routes file
 | 
						|
#The format is: destination  gateway  mask  ifname
 | 
						|
sub addPersistentRoute_Sles {
 | 
						|
    my $callback=shift;
 | 
						|
    my $net=shift;
 | 
						|
    my $mask=shift;
 | 
						|
    my $gw_ip=shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $ifname=shift;
 | 
						|
 | 
						|
    my $host=hostname();
 | 
						|
    
 | 
						|
    my $filename="/etc/sysconfig/network/routes";
 | 
						|
    my @output=getConfig($filename);
 | 
						|
    #print "old output=" . join("\n", @output) . "\n";
 | 
						|
    my $hasConfiged=0;
 | 
						|
    if (@output && (@output > 0)) {
 | 
						|
	$hasConfiged=checkConfig_Sles($net, $mask, $gw_ip, $gw, \@output);
 | 
						|
    }
 | 
						|
    #print "hasConfiged=$hasConfiged\n";
 | 
						|
    my $new_config;
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        $new_config = "$net/$mask $gw_ip - -\n";
 | 
						|
    } else {
 | 
						|
        $new_config="$net $gw_ip $mask $ifname\n";
 | 
						|
    }
 | 
						|
    if (!$hasConfiged) {
 | 
						|
	push(@output, $new_config);
 | 
						|
	#print "new output=" . join("\n", @output) . "\n";
 | 
						|
	#Add the route to the configuration file
 | 
						|
        #the format is: destination  gateway  mask  ifname
 | 
						|
	setConfig($filename, \@output);
 | 
						|
 | 
						|
	chomp($new_config);
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Added persistent route \"$new_config\" to $filename.";
 | 
						|
	$callback->($rsp);
 | 
						|
    } else {
 | 
						|
	chomp($new_config);
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Persistent route \"$new_config\" already exists in $filename.";
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#remove the routes from the /etc/sysconfig/network/routes file
 | 
						|
sub deletePersistentRoute_Sles {
 | 
						|
    my $callback=shift;
 | 
						|
    my $net=shift;
 | 
						|
    my $mask=shift;
 | 
						|
    my $gw_ip=shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $ifname=shift;
 | 
						|
    
 | 
						|
    my $host=hostname();
 | 
						|
 | 
						|
    my $filename="/etc/sysconfig/network/routes";
 | 
						|
    my @output=getConfig($filename);
 | 
						|
    #print "old output=" . join("\n", @output) . "\n";
 | 
						|
    my @new_output=();
 | 
						|
    my $bigfound=0;
 | 
						|
    foreach my $tmp_conf (@output) {
 | 
						|
	my $found = checkConfig_Sles($net, $mask, $gw_ip, $gw, [$tmp_conf]); 
 | 
						|
	if (!$found) {
 | 
						|
	    push(@new_output, $tmp_conf);
 | 
						|
	} else {
 | 
						|
	    $bigfound=1;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    #print "new output=" . join("\n", @new_output) . "\n";
 | 
						|
    #set the new configuration to the configuration file
 | 
						|
    setConfig($filename, \@new_output);
 | 
						|
    if ($bigfound) {
 | 
						|
	my $rsp={};
 | 
						|
        if ($net =~ /:/) {
 | 
						|
            $rsp->{data}->[0]= "$host: Removed persistent route \"$net/$mask $gw_ip\" from $filename.";
 | 
						|
        } else {
 | 
						|
    	    $rsp->{data}->[0]= "$host: Removed persistent route \"$net $gw_ip $mask $ifname\" from $filename.";
 | 
						|
        }
 | 
						|
	$callback->($rsp);
 | 
						|
    } else {
 | 
						|
	my $rsp={};
 | 
						|
        if ($net =~ /:/) {
 | 
						|
	    $rsp->{data}->[0]= "$host: Persistent route \"$net/$mask $gw_ip\" does not exist in $filename.";
 | 
						|
        } else {
 | 
						|
	    $rsp->{data}->[0]= "$host: Persistent route \"$net $gw_ip $mask $ifname\" does not exist in $filename.";
 | 
						|
        }
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#check if the route is in the SLES network configuration file
 | 
						|
sub checkConfig_Sles {
 | 
						|
    my $net = shift;
 | 
						|
    my $mask = shift;
 | 
						|
    my $gw_ip = shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $output=shift;
 | 
						|
 | 
						|
    # ipv4 format: 192.168.0.0 207.68.156.51 255.255.0.0 eth1
 | 
						|
    # ipv6 format: fd59::/64 fd57:faaf:e1ab:336:21a:64ff:fe01:1 - -
 | 
						|
    foreach my $line (@$output) {
 | 
						|
	my @a=split(' ', $line);
 | 
						|
	my ($net1,$mask1,$gw1);
 | 
						|
        if ($net =~ /:/) {
 | 
						|
            if (@a>0) {
 | 
						|
                my $ipv6net = $a[0];
 | 
						|
                ($net1,$mask1) = split("/",$ipv6net);
 | 
						|
            }
 | 
						|
	    if (@a>1) { 
 | 
						|
	        $gw1=$a[1];
 | 
						|
	        if ($gw1 eq '-') { $gw1=$gw_ip; }
 | 
						|
            }
 | 
						|
 | 
						|
	} else {
 | 
						|
	    if (@a>0) { 
 | 
						|
	       $net1=$a[0];
 | 
						|
	       if ($net1 eq '-') { $net1=$net;}
 | 
						|
	   }
 | 
						|
	    if (@a>1) { 
 | 
						|
	        $gw1=$a[1];
 | 
						|
	        if ($gw1 eq '-') { $gw1=$gw_ip; }
 | 
						|
	    }
 | 
						|
	    if (@a>2) { 
 | 
						|
	        $mask1=$a[2];
 | 
						|
	        if ($mask1 eq '-') { $mask1=$mask;}
 | 
						|
	    }
 | 
						|
       }
 | 
						|
 | 
						|
	#print "net=$net1,$net mask=$mask1,$mask gw=$gw1,$gw_ip\n";
 | 
						|
	if (($net1 && $net1 eq $net) && ($mask1 && $mask1 eq $mask) && (($gw1 && $gw1 eq $gw) || ($gw1 && $gw1 eq $gw_ip)))  {
 | 
						|
	    return 1;
 | 
						|
	}    
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
#add the routes to the /etc/sysconfig/static-routes file
 | 
						|
#The format is: any net 172.16.0.0 netmask 255.240.0.0 gw 192.168.0.1 eth0
 | 
						|
sub addPersistentRoute_RH {
 | 
						|
    my $callback=shift;
 | 
						|
    my $net=shift;
 | 
						|
    my $mask=shift;
 | 
						|
    my $gw_ip=shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $ifname=shift;
 | 
						|
 | 
						|
    my $host=hostname();
 | 
						|
    
 | 
						|
    my $filename;
 | 
						|
    # ipv6
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        $filename="/etc/sysconfig/static-routes-ipv6";
 | 
						|
    } else {
 | 
						|
        $filename="/etc/sysconfig/static-routes";
 | 
						|
    }
 | 
						|
    my @output=getConfig($filename);
 | 
						|
    #print "old output=" . join("\n", @output) . "\n";
 | 
						|
    my $hasConfiged=0;
 | 
						|
    if (@output && (@output > 0)) {
 | 
						|
	$hasConfiged=checkConfig_RH($net, $mask, $gw_ip, $gw, \@output);
 | 
						|
    }
 | 
						|
    #print "hasConfiged=$hasConfiged\n";
 | 
						|
    my $new_config;
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        # ifname is required for ipv6 routing
 | 
						|
        if (!$ifname) {
 | 
						|
	        my $rsp={};
 | 
						|
	        $rsp->{data}->[0]= "$host: Could not add persistent route for ipv6 network $net/$mask, the ifname is required in the routes table.";
 | 
						|
	        $callback->($rsp);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $new_config="$ifname $net/$mask $gw_ip";
 | 
						|
    } else {
 | 
						|
        $new_config="any net $net netmask $mask gw $gw_ip $ifname\n";
 | 
						|
    }
 | 
						|
    if (!$hasConfiged) {
 | 
						|
	push(@output, $new_config);
 | 
						|
	#print "new output=" . join("\n", @output) . "\n";
 | 
						|
	#Add the route to the configuration file
 | 
						|
        #the format is: destination  gateway  mask  ifname
 | 
						|
	setConfig($filename, \@output);
 | 
						|
	
 | 
						|
	chomp($new_config);
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Added persistent route \"$new_config\" to $filename.";
 | 
						|
	$callback->($rsp);
 | 
						|
    } else {
 | 
						|
	chomp($new_config);
 | 
						|
	my $rsp={};
 | 
						|
	$rsp->{data}->[0]= "$host: Persistent route \"$new_config\" already exists in $filename.";
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#remove the routes from the /etc/sysconfig/static-routes file
 | 
						|
sub deletePersistentRoute_RH {
 | 
						|
    my $callback=shift;
 | 
						|
    my $net=shift;
 | 
						|
    my $mask=shift;
 | 
						|
    my $gw_ip=shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $ifname=shift;
 | 
						|
 | 
						|
    my $host=hostname();
 | 
						|
    
 | 
						|
    my $filename;
 | 
						|
    # ipv6
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        $filename="/etc/sysconfig/static-routes-ipv6";
 | 
						|
    } else {
 | 
						|
        $filename="/etc/sysconfig/static-routes";
 | 
						|
    }
 | 
						|
    my @output=getConfig($filename);
 | 
						|
    #print "old output=" . join("\n", @output) . "\n";
 | 
						|
    my @new_output=();
 | 
						|
    my $bigfound=0;
 | 
						|
    foreach my $tmp_conf (@output) {
 | 
						|
	my $found = checkConfig_RH($net, $mask, $gw_ip, $gw, [$tmp_conf]); 
 | 
						|
	if (!$found) {
 | 
						|
	    push(@new_output, $tmp_conf);
 | 
						|
	} else {
 | 
						|
	    $bigfound=1;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    #print "new output=" . join("\n", @new_output) . "\n";
 | 
						|
    #set the new configuration to the configuration file
 | 
						|
    setConfig($filename, \@new_output);
 | 
						|
    if ($bigfound) {
 | 
						|
	my $rsp={};
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        $rsp->{data}->[0]= "$host: Removed persistent route \"$ifname $net/$mask $gw_ip\" from $filename.";
 | 
						|
    } else {
 | 
						|
        $rsp->{data}->[0]= "$host: Removed persistent route \"any net $net netmask $mask gw $gw_ip $ifname\" from $filename.";
 | 
						|
    }
 | 
						|
	$callback->($rsp);
 | 
						|
    } else {
 | 
						|
	my $rsp={};
 | 
						|
    if ($net =~ /:/) {
 | 
						|
	    $rsp->{data}->[0]= "$host: Persistent route \"$ifname $net/$mask $gw_ip\" does not exist in $filename.";
 | 
						|
    } else {
 | 
						|
	    $rsp->{data}->[0]= "$host: Persistent route \"any net $net netmask $mask gw $gw_ip $ifname\" does not exist in $filename.";
 | 
						|
    }
 | 
						|
	$callback->($rsp);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
sub checkConfig_RH {
 | 
						|
    my $net = shift;
 | 
						|
    my $mask = shift;
 | 
						|
    my $gw_ip = shift;
 | 
						|
    my $gw=shift;
 | 
						|
    my $output=shift;
 | 
						|
 | 
						|
    foreach my $line (@$output) {
 | 
						|
	my @a=split(' ', $line);
 | 
						|
    #The format is: any net 172.16.0.0 netmask 255.240.0.0 gw 192.168.0.1 eth0
 | 
						|
    # ipv6 format: eth1 fd60::/64 fd57::214:5eff:fe15:1
 | 
						|
	my ($net1,$mask1,$gw1);
 | 
						|
    if ($net =~ /:/) {
 | 
						|
        if (@a>1) {
 | 
						|
            my $ipv6net = $a[1];
 | 
						|
            ($net1,$mask1) = split("/",$ipv6net);
 | 
						|
        }
 | 
						|
        if (@a>2) {
 | 
						|
            $gw1 = $a[2];
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
	    if (@a>2) { 
 | 
						|
	        $net1=$a[2];
 | 
						|
	        if ($net1 eq '-') { $net1=$net;}
 | 
						|
	    }
 | 
						|
	    if (@a>4) { 
 | 
						|
	        $mask1=$a[4];
 | 
						|
	        if ($mask1 eq '-') { $mask1=$mask;}
 | 
						|
    	}
 | 
						|
    	if (@a>6) { 
 | 
						|
	        $gw1=$a[6];
 | 
						|
	        if ($gw1 eq '-') { $gw1=$gw_ip; }
 | 
						|
	    }
 | 
						|
    }
 | 
						|
 | 
						|
	#print "net=$net1,$net mask=$mask1,$mask gw=$gw1,$gw_ip\n";
 | 
						|
	if (($net1 && $net1 eq $net) && ($mask1 && $mask1 eq $mask) && (($gw1 && $gw1 eq $gw) || ($gw1 && $gw1 eq $gw_ip)))  {
 | 
						|
	    return 1;
 | 
						|
	}    
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
	
 | 
						|
 | 
						|
 |