Commit 4207d74b authored by Leigh B. Stoller's avatar Leigh B. Stoller
Browse files

The client side of recent tunnel changes. Now support gre and vtun

tunnels.
parent ed47b9c4
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2004, 2005, 2006 University of Utah and the Flux Group.
# Copyright (c) 2004-2008 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -131,6 +131,7 @@ sub doboot()
my $aliases = $ifconfig->{ALIASES};
my $iface = $ifconfig->{IFACE};
my $settings = $ifconfig->{SETTINGS};
my $lan = $ifconfig->{LAN};
my $ifrtabid = undef;
#
......@@ -161,7 +162,8 @@ sub doboot()
my ($upline, $downline) =
os_ifconfig_line($iface, $inet, $mask,
$speed, $duplex, $aliases,
$type, $settings, $ifrtabid, \%oscookie);
$type, $lan, $settings,
$ifrtabid, \%oscookie);
if (defined($upline) && $upline) {
$upcmds .= "$upline\n ";
......
......@@ -7,6 +7,7 @@
use English;
use Getopt::Std;
use POSIX qw(setsid);
use Data::Dumper;
sub usage()
{
......@@ -41,6 +42,7 @@ my @vtundpids = ();
# library and initialize itself.
#
use libsetup;
use liblocsetup;
use libtmcc;
use librc;
......@@ -59,6 +61,8 @@ sub doboot();
sub doshutdown();
sub doreconfig();
sub docleanup();
sub DoVtun($);
sub DoGRE($);
# After libsetup include; tunnels run outside in fake vnode setup.
my $PIDFILE = CONFDIR() . "/tunnel.pid";
......@@ -123,20 +127,27 @@ sub Pcleanup($)
#
sub doboot()
{
my @tunnels;
my $tunnels;
print STDOUT "Checking Testbed tunnel configuration ... \n";
if (gettunnelconfig(\@tunnels)) {
if (gettunnelconfig(\$tunnels)) {
fatal("Could not get tunnel configuration from libsetup!");
}
unlink $VTUNDCONFIG;
return
if (!@tunnels);
if (!keys(%{ $tunnels }));
# XXX
system("kldload if_tap");
my $sysname = `uname -s`;
chomp($sysname);
if ($sysname eq "Linux") {
system("insmod ip_gre");
}
else {
system("kldload if_tap");
}
#
# Write our pid to a file so we can be killed later.
......@@ -148,6 +159,39 @@ sub doboot()
$SIG{INT} = \&Pcleanup;
$SIG{HUP} = \&Pcleanup;
#
# First check for vtun.
#
DoVtun($tunnels);
DoGRE($tunnels);
# No reason to daemonize ...
return
if (!@vtundpids);
#
# Now daemonize and let the boot continue.
#
if (TBBackGround($LOGFILE)) {
sleep(1);
exit(0);
}
# Fully disconnect from bootup.
setsid();
#
# Just wait. We will die via the signal handler above.
#
while (1) {
sleep(10000);
}
return;
}
sub DoVtun($)
{
my ($tunnels) = @_;
my ($pid, $eid, $vname) = check_nickname();
if (! open(CONF, ">$VTUNDCONFIG")) {
......@@ -167,21 +211,29 @@ sub doboot()
" type ether;\n".
"}\n".
"\n");
#
# First construct the config file.
#
foreach my $tunnel (@tunnels) {
my $name = $tunnel->{"NAME"};
my $isserver = $tunnel->{"ISSERVER"};
my $peeraddr = $tunnel->{"PEERIPADDR"};
my $peerport = $tunnel->{"PEERPORT"};
my $password = $tunnel->{"PASSWORD"};
my $encrypt = ($tunnel->{"ENCRYPT"} ? "yes" : "no");
my $compress = ($tunnel->{"COMPRESS"} ? "yes" : "no");
my $inetip = $tunnel->{"IPADDR"};
my $mask = $tunnel->{"IPMASK"};
my $proto = $tunnel->{"PROTO"};
foreach my $tunnel (values(%{ $tunnels })) {
next
if ($tunnel->{"tunnel_style"} ne "vtun");
my $name = $tunnel->{"tunnel_lan"};
my $isserver = $tunnel->{"tunnel_isserver"};
my $destaddr = $tunnel->{"tunnel_dstip"};
my $dstport = $tunnel->{"tunnel_serverport"};
my $password = $tunnel->{"tunnel_secretkey"};
my $encrypt = $tunnel->{"tunnel_encrypt"};
my $compress = $tunnel->{"tunnel_compress"};
my $inetip = $tunnel->{"tunnel_ip"};
my $mask = $tunnel->{"tunnel_ipmask"};
my $proto = $tunnel->{"tunnel_proto"};
$proto = "udp"
if (!defined($proto));
$encrypt = (defined($encrypt) && $encrypt ? "yes" : "no");
$compress = (defined($compress) && $compress ? "yes" : "no");
#
# Sheesh, vtund fails if it sees "//" in a path.
......@@ -218,20 +270,23 @@ sub doboot()
#
# Now fire off the vtund processes
#
foreach my $tunnel (@tunnels) {
my $name = $tunnel->{"NAME"};
my $isserver = $tunnel->{"ISSERVER"};
my $peeraddr = $tunnel->{"PEERIPADDR"};
my $peerport = $tunnel->{"PEERPORT"};
my $password = $tunnel->{"PASSWORD"};
my $encrypt = ($tunnel->{"ENCRYPT"} ? "yes" : "no");
my $compress = ($tunnel->{"COMPRESS"} ? "yes" : "no");
my $inetip = $tunnel->{"IPADDR"};
my $mask = $tunnel->{"IPMASK"};
my $proto = $tunnel->{"PROTO"};
foreach my $tunnel (values(%{ $tunnels })) {
next
if ($tunnel->{"tunnel_style"} ne "vtun");
my $name = $tunnel->{"tunnel_lan"};
my $isserver = $tunnel->{"tunnel_isserver"};
my $destaddr = $tunnel->{"tunnel_dstip"};
my $dstport = $tunnel->{"tunnel_serverport"};
my $password = $tunnel->{"tunnel_secretkey"};
my $encrypt = $tunnel->{"tunnel_encrypt"};
my $compress = $tunnel->{"tunnel_compress"};
my $inetip = $tunnel->{"tunnel_ip"};
my $mask = $tunnel->{"tunnel_ipmask"};
my $proto = $tunnel->{"tunnel_proto"};
my $log;
my $cmd = "$VTUND -n -P $peerport -f $VTUNDCONFIG ";
my $cmd = "$VTUND -n -P $dstport -f $VTUNDCONFIG ";
if ($isserver) {
if (!$didserver) {
......@@ -241,7 +296,7 @@ sub doboot()
}
}
else {
$cmd .= "$name $peeraddr";
$cmd .= "$name $destaddr";
$log = "$LOGDIR/vtun-${pid}-${eid}-${name}.debug";
}
......@@ -279,24 +334,33 @@ sub doboot()
" Could not exec $cmd\n");
}
}
}
sub DoGRE($)
{
my ($tunnels) = @_;
my ($pid, $eid, $vname) = check_nickname();
#
# Now daemonize and let the boot continue.
#
if (TBBackGround($LOGFILE)) {
sleep(1);
exit(0);
}
# Fully disconnect from bootup.
setsid();
#
# Just wait. We will die via the signal handler above.
#
while (1) {
sleep(10000);
# First construct the config file.
#
foreach my $tunnel (values(%{ $tunnels })) {
next
if ($tunnel->{"tunnel_style"} ne "gre");
my $name = $tunnel->{"tunnel_lan"};
my $srchost = $tunnel->{"tunnel_srcip"};
my $dsthost = $tunnel->{"tunnel_dstip"};
my $inetip = $tunnel->{"tunnel_ip"};
my $peerip = $tunnel->{"tunnel_peerip"};
my $mask = $tunnel->{"tunnel_ipmask"};
my $unit = $tunnel->{"tunnel_unit"};
os_config_gre($name, $unit,
$inetip, $peerip, $mask, $srchost, $dsthost)
== 0 or fatal("Could not configure gre tunnel!");
}
return;
}
#
......
......@@ -47,7 +47,7 @@ use libtmcc;
#
# BE SURE TO BUMP THIS AS INCOMPATIBILE CHANGES TO TMCD ARE MADE!
#
sub TMCD_VERSION() { 27; };
sub TMCD_VERSION() { 28; };
libtmcc::configtmcc("version", TMCD_VERSION());
# Control tmcc timeout.
......@@ -1181,42 +1181,29 @@ sub gettraceconfig($)
sub gettunnelconfig($)
{
my ($rptr) = @_;
my @tunnels = ();
my $tunnels = {};
if (tmcc(TMCCCMD_TUNNEL, undef, \@tmccresults) < 0) {
warn("*** WARNING: Could not get tunnel config from server!\n");
return -1;
}
my $pat = q(TUNNEL=([-\w.]+) ISSERVER=(\d) PEERIP=([-\w.]+) );
$pat .= q(PEERPORT=(\d+) PASSWORD=([-\w.]+) );
$pat .= q(ENCRYPT=(\d) COMPRESS=(\d) INET=([-\w.]+) );
$pat .= q(MASK=([-\w.]+) PROTO=([-\w.]+));
my $pat = q(TUNNEL=([\w]+) MEMBER=([\w]+) KEY='(.*)' VALUE='(.*)');
foreach my $str (@tmccresults) {
if ($str =~ /$pat/) {
my $tunnel = {};
my $tunnel = $1;
my $member = $2;
my $key = $3;
my $value = $4;
#
# The following is rather specific to vtund!
#
$tunnel->{"NAME"} = $1;
$tunnel->{"ISSERVER"} = $2;
$tunnel->{"PEERIPADDR"} = $3;
$tunnel->{"PEERPORT"} = $4;
$tunnel->{"PASSWORD"} = $5;
$tunnel->{"ENCRYPT"} = $6;
$tunnel->{"COMPRESS"} = $7;
$tunnel->{"IPADDR"} = $8;
$tunnel->{"IPMASK"} = $9;
$tunnel->{"PROTO"} = $10;
push(@tunnels, $tunnel);
$tunnels->{"$tunnel:$member"}->{$key} = $value;
}
else {
warn("*** WARNING: Bad tunnels line: $str\n");
}
}
@$rptr = @tunnels;
$$rptr = $tunnels;
return 0;
}
......
......@@ -21,7 +21,7 @@ use Exporter;
os_routing_enable_forward os_routing_enable_gated
os_routing_add_manual os_routing_del_manual os_homedirdel
os_groupdel os_getnfsmounts os_islocaldir
os_fwconfig_line os_fwrouteconfig_line
os_fwconfig_line os_fwrouteconfig_line os_config_gre
);
# Must come after package declaration!
......@@ -115,9 +115,9 @@ sub os_account_cleanup()
# Generate and return an ifconfig line that is approriate for putting
# into a shell script (invoked at bootup).
#
sub os_ifconfig_line($$$$$$$;$$%)
sub os_ifconfig_line($$$$$$$$;$$%)
{
my ($iface, $inet, $mask, $speed, $duplex, $aliases, $iface_type,
my ($iface, $inet, $mask, $speed, $duplex, $aliases, $iface_type, $lan,
$settings, $rtabid, $cookie) = @_;
my $media = "";
my $mediaopt = "";
......@@ -182,7 +182,9 @@ sub os_ifconfig_line($$$$$$$;$$%)
# Config the interface.
$uplines .= sprintf($IFCONFIG, $iface, $inet, $mask,
$media, $mediaopt);
$downlines = "$IFCONFIGBIN $iface down";
# An interface underlying virtual interfaces does not go down.
$downlines = "$IFCONFIGBIN $iface down"
if (defined($lan) && $lan ne "");
}
return ($uplines, $downlines);
}
......@@ -832,4 +834,28 @@ sub os_fwrouteconfig_line($$$)
return ($upline, $downline);
}
sub os_config_gre($$$$$$$)
{
my ($name, $unit, $inetip, $peerip, $mask, $srchost, $dsthost) = @_;
my $gre = `ifconfig gre create`;
if ($?) {
warn("*** Could not create a new gre device.\n");
return -1;
}
if ($gre =~ /^(gre\d*)$/) {
$gre = $1;
}
else {
warn("*** Cannot parse gre device '$gre'\n");
return -1;
}
if (system("ifconfig $gre $inetip $peerip link1 netmask $mask up") ||
system("ifconfig $gre tunnel $srchost $dsthost")) {
warn("Could not start tunnel!\n");
return -1;
}
return 0;
}
1;
......@@ -12,14 +12,15 @@ package liblocsetup;
use Exporter;
@ISA = "Exporter";
@EXPORT =
qw ( $CP $EGREP $NFSMOUNT $UMOUNT $TMPASSWD $SFSSD $SFSCD $RPMCMD $HOSTSFILE
qw ( $CP $EGREP $NFSMOUNT $UMOUNT $TMPASSWD $SFSSD $SFSCD $RPMCMD
$HOSTSFILE $LOOPBACKMOUNT
os_account_cleanup os_ifconfig_line os_etchosts_line
os_setup os_groupadd os_useradd os_userdel os_usermod os_mkdir
os_ifconfig_veth os_viface_name
os_routing_enable_forward os_routing_enable_gated
os_routing_add_manual os_routing_del_manual os_homedirdel
os_groupdel os_getnfsmounts os_islocaldir
os_fwconfig_line os_fwrouteconfig_line
os_fwconfig_line os_fwrouteconfig_line os_config_gre
);
# Must come after package declaration!
......@@ -52,6 +53,7 @@ $CP = "/bin/cp";
$DF = "/bin/df";
$EGREP = "/bin/egrep -q";
$NFSMOUNT = "/bin/mount -o vers=2,udp"; # Force NFS Version 2 over UDP
$LOOPBACKMOUNT = "/sbin/mount --bind ";
$UMOUNT = "/bin/umount";
$TMPASSWD = "$ETCDIR/passwd";
$SFSSD = "/usr/local/sbin/sfssd";
......@@ -1417,4 +1419,20 @@ sub getCurrentIwconfig($;$) {
return \%r;
}
sub os_config_gre($$$$$$$)
{
my ($name, $unit, $inetip, $peerip, $mask, $srchost, $dsthost) = @_;
my $dev = "$name$unit";
if (system("ip tunnel add $dev mode gre remote $dsthost local $srchost") ||
system("ip link set $dev up") ||
system("ip addr add $inetip dev $dev") ||
system("ifconfig $dev netmask $mask")) {
warn("Could not start tunnel!\n");
return -1;
}
return 0;
}
1;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment