makeroutes phase 1
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@6260 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
e77d87cf4c
commit
fe30dd3adc
@ -338,4 +338,32 @@ sub ishostinsubnet {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 setup_ip_forwarding
|
||||
|
||||
Sets up ip forwarding on localhost
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub setup_ip_forwarding
|
||||
{
|
||||
my ($class, $enable)=@_;
|
||||
if (xCAT::Utils->isLinux()) {
|
||||
my $conf_file="/etc/sysctl.conf";
|
||||
`grep "net.ipv4.ip_forward" $conf_file`;
|
||||
if ($? == 0) {
|
||||
`sed -i "s/^net.ipv4.ip_forward = .*/net.ipv4.ip_forward = $enable/" $conf_file`;
|
||||
} else {
|
||||
`echo "net.ipv4.ip_forward = $enable" >> $conf_file`;
|
||||
}
|
||||
`sysctl -p $conf_file`;
|
||||
}
|
||||
else
|
||||
{ #AIX: TODO
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -884,6 +884,21 @@ prescripts => {
|
||||
},
|
||||
},
|
||||
|
||||
routes => {
|
||||
cols => [qw(routename net mask gateway ifname comments disable)],
|
||||
keys => [qw(routename)],
|
||||
table_desc => 'Describes the additional routes needed to be setup in the os routing table. These routes usually are used to connect the management node to the compute node using the servie node as gateway.',
|
||||
descriptions => {
|
||||
routename => 'Name used to identify this route.',
|
||||
net => 'The network address.',
|
||||
mask => 'The network mask.',
|
||||
ifname => 'The interface name of the management node facing the gateway.',
|
||||
gateway => 'The gateway that routes the ip traffic from the mn to the nodes. It is usually a service node.',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
|
||||
zvm => {
|
||||
cols => [qw(node hcp userid comments disable)],
|
||||
keys => [qw(node)],
|
||||
@ -959,6 +974,7 @@ foreach my $tabname (keys(%xCAT::ExtTab::ext_tabspec)) {
|
||||
node => { attrs => [], attrhash => {}, objkey => 'node' },
|
||||
osimage => { attrs => [], attrhash => {}, objkey => 'imagename' },
|
||||
network => { attrs => [], attrhash => {}, objkey => 'netname' },
|
||||
route => { attrs => [], attrhash => {}, objkey => 'routename' },
|
||||
group => { attrs => [], attrhash => {}, objkey => 'groupname' },
|
||||
site => { attrs => [], attrhash => {}, objkey => 'master' },
|
||||
policy => { attrs => [], attrhash => {}, objkey => 'priority' },
|
||||
@ -1857,6 +1873,37 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs);
|
||||
access_tabentry => 'networks.netname=attr:netname',
|
||||
},
|
||||
);
|
||||
#########################
|
||||
# route data object #
|
||||
#########################
|
||||
# routes table #
|
||||
#########################
|
||||
@{$defspec{route}->{'attrs'}} = (
|
||||
{attr_name => 'routename',
|
||||
tabentry => 'routes.routename',
|
||||
access_tabentry => 'routes.routename=attr:routename',
|
||||
},
|
||||
{attr_name => 'net',
|
||||
tabentry => 'routes.net',
|
||||
access_tabentry => 'routes.routename=attr:routename',
|
||||
},
|
||||
{attr_name => 'mask',
|
||||
tabentry => 'routes.mask',
|
||||
access_tabentry => 'routes.routename=attr:routename',
|
||||
},
|
||||
{attr_name => 'gateway',
|
||||
tabentry => 'routes.gateway',
|
||||
access_tabentry => 'routes.routename=attr:routename',
|
||||
},
|
||||
{attr_name => 'ifname',
|
||||
tabentry => 'routes.ifname',
|
||||
access_tabentry => 'routes.routename=attr:routename',
|
||||
},
|
||||
{attr_name => 'usercomment',
|
||||
tabentry => 'routes.comments',
|
||||
access_tabentry => 'routes.routename=attr:routename',
|
||||
},
|
||||
);
|
||||
|
||||
#####################
|
||||
# site data object #
|
||||
|
@ -6,6 +6,7 @@ use strict;
|
||||
use xCAT::Table;
|
||||
|
||||
use xCAT::Utils;
|
||||
use xCAT::NetworkUtils;
|
||||
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT_plugin::dhcp;
|
||||
@ -256,11 +257,22 @@ sub init_plugin
|
||||
if (grep(/$service/, @servicelist))
|
||||
{
|
||||
|
||||
$rc = &setup_ip_forwarding($nodename, $doreq); # setup ip forwarding
|
||||
$rc = xCAT::NetworkUtils->setup_ip_forwarding(1); # enable ip forwarding
|
||||
if ($rc == 0)
|
||||
{
|
||||
xCAT::Utils->update_xCATSN($service);
|
||||
}
|
||||
} else {
|
||||
|
||||
$rc = xCAT::NetworkUtils->setup_ip_forwarding(0); # disable ip forwarding
|
||||
if ($rc == 0)
|
||||
{
|
||||
#remove the service from the /etc/xCATSN file
|
||||
my $text=`sed -e "/$service/d" /etc/xCATSN`;
|
||||
if ($?==0) {
|
||||
`echo "$text" > /etc/xCATSN`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else # management node
|
||||
@ -1244,33 +1256,5 @@ sub setup_HTTP
|
||||
return $rc;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 setup_ip_forwarding
|
||||
|
||||
Sets up ip forwarding on the sn
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub setup_ip_forwarding
|
||||
{
|
||||
my $rc=0;
|
||||
if (xCAT::Utils->isLinux()) {
|
||||
my $conf_file="/etc/sysctl.conf";
|
||||
$rc=`grep "net.ipv4.ip_forward" $conf_file`;
|
||||
if ($? == 0) {
|
||||
`sed -i "s/^net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/" $conf_file`;
|
||||
} else {
|
||||
`echo "net.ipv4.ip_forward = 1" >> $conf_file`;
|
||||
}
|
||||
$rc = `sysctl -p $conf_file`;
|
||||
}
|
||||
else
|
||||
{ #AIX: TODO
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
400
xCAT-server/lib/xcat/plugins/route.pm
Normal file
400
xCAT-server/lib/xcat/plugins/route.pm
Normal file
@ -0,0 +1,400 @@
|
||||
# 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::NetworkUtils;
|
||||
use xCAT::MsgUtils;
|
||||
use Getopt::Long;
|
||||
use xCAT::NodeRange;
|
||||
use Data::Dumper;
|
||||
|
||||
|
||||
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];
|
||||
|
||||
#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 {
|
||||
my $reqcopy = {%$request};
|
||||
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
||||
return [$reqcopy];
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=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 $args = $request->{arg};
|
||||
|
||||
# parse the options
|
||||
@ARGV=();
|
||||
if ($args) {
|
||||
@ARGV=@{$args};
|
||||
}
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
|
||||
my $netmask_in;
|
||||
my $net_in;
|
||||
my $gateway_in;
|
||||
my $routelist_in;
|
||||
my $delete=0;
|
||||
if(!GetOptions(
|
||||
'h|help' => \$::HELP,
|
||||
'v|version' => \$::VERSION,
|
||||
'r|routename=s' => \$routelist_in,
|
||||
'n|net=s' => \$net_in,
|
||||
'm|mask=s' => \$netmask_in,
|
||||
'g|gateway=s' => \$gateway_in,
|
||||
'd|delete' => \$delete,))
|
||||
{
|
||||
&usage($callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# display the usage if -h or --help is specified
|
||||
if ($::HELP) {
|
||||
&usage($callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (@ARGV > 0) {
|
||||
&usage($callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($::VERSION)
|
||||
{
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= xCAT::Utils->Version();
|
||||
$callback->($rsp);
|
||||
return 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 (defined(@tmp1) && (@tmp1 > 0)) {
|
||||
foreach(@tmp1) {
|
||||
$all_routes{$_->{routename}} = $_;
|
||||
$_->{process} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#print Dumper(%all_routes);
|
||||
|
||||
#get the routes to be handled
|
||||
if ($routelist_in) {
|
||||
if ($net_in || $gateway_in || $netmask_in) {
|
||||
my $rsp={};
|
||||
$rsp->{error}->[0]= "-r cannot be combined with -n,-g or -m flag.";
|
||||
$callback->($rsp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#check if the route names are valid
|
||||
foreach(split(',', $routelist_in)) {
|
||||
if (! exists($all_routes{$_})) {
|
||||
my $rsp={};
|
||||
$rsp->{error}->[0]= "route $_ is not defined in the routes table.";
|
||||
$callback->($rsp);
|
||||
return 1;
|
||||
} else {
|
||||
$all_routes{$_}->{process}=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ( $net_in || $gateway_in || $netmask_in) {
|
||||
my $count=0;
|
||||
foreach (keys %all_routes) {
|
||||
my $process=1;
|
||||
if (($net_in) && ($all_routes{$_}->{net} ne $net_in)) { $process=0; }
|
||||
if (($netmask_in) && ($all_routes{$_}->{mask} ne $netmask_in)) { $process=0; }
|
||||
if (($gateway_in) && ($all_routes{$_}->{gateway} ne $gateway_in)) { $process=0; }
|
||||
$all_routes{$_}->{process}=$process;
|
||||
|
||||
if ($process == 1) { $count++; }
|
||||
}
|
||||
if ($count==0) {
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= "No route in the routes table matches the input.";
|
||||
$callback->($rsp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#handle all routes
|
||||
foreach (keys %all_routes) {
|
||||
$all_routes{$_}->{process}= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#print Dumper(%all_routes);
|
||||
|
||||
#now let handle the route creatation and deletion
|
||||
my @sns=();
|
||||
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 ($delete) {
|
||||
delete_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name);
|
||||
}
|
||||
else {
|
||||
set_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#not all gateways are service nodes
|
||||
my %sn_hash=();
|
||||
my @allSN=xCAT::Utils->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";
|
||||
$rsp->{data}->[3]= " makeroutes -d";
|
||||
$rsp->{data}->[4]= " makeroutes -r routename[,routename...]";
|
||||
$rsp->{data}->[5]= " makeroutes -r routename[,routename...] -d";
|
||||
$rsp->{data}->[6]= " makeroutes [-n network] [-m mask] [-g gateway]";
|
||||
$rsp->{data}->[7]= " makeroutes [-n network] [-m mask]] [-g gateway] -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 $result;
|
||||
$result=`route|grep $net`;
|
||||
if ($? == 0) {
|
||||
if ($result) {
|
||||
my @b=split('\n', $result);
|
||||
foreach my $tmp (@b) {
|
||||
chomp($tmp);
|
||||
my @a=split(' ', $tmp);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 $result;
|
||||
if (!route_exists($net, $mask, $gw_ip, $gw)) {
|
||||
#set temporay route
|
||||
print "cmd=route add -net $net netmask $mask gw $gw_ip\n";
|
||||
$result=`route add -net $net netmask $mask gw $gw_ip 2>&1`;
|
||||
if ($? != 0) {
|
||||
my $rsp={};
|
||||
$rsp->{error}->[0]= "route add -net $net netmask $mask gw $gw_ip\nerror code=$?, result=$result\n";
|
||||
$callback->($rsp);
|
||||
return 1;
|
||||
} else {
|
||||
#set per permanent route
|
||||
}
|
||||
}
|
||||
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 $result;
|
||||
if (route_exists($net, $mask, $gw_ip, $gw)) {
|
||||
#delete route temporarily
|
||||
print "cmd=route delete -net $net netmask $mask gw $gw_ip\n";
|
||||
$result=`route delete -net $net netmask $mask gw $gw_ip 2>&1`;
|
||||
if ($? != 0) {
|
||||
my $rsp={};
|
||||
$rsp->{error}->[0]= "route delete -net $net netmask $mask gw $gw_ip\nerror code=$?, result=$result\n";
|
||||
$callback->($rsp);
|
||||
return 1;
|
||||
} else {
|
||||
#delete route permanently
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user