Index: fedkit/active_config.pl
===================================================================
--- fedkit/active_config.pl	(revision 37f6592eb7f1f642a95968caad9b140737250a02)
+++ fedkit/active_config.pl	(revision f8fa72ba913bb6209f71fb3ea1dafb371d25a87b)
@@ -17,5 +17,5 @@
 my $iface_file = "/var/emulab/boot/ifmap";
 my $ssh = "/usr/bin/ssh";
-my $use_file;
+my $ssh_port = 22;
 
 my %opts = (
@@ -28,4 +28,5 @@
     'interfaces=s' => \$iface_file,
     'ssh=s' => \$ssh,
+    'ssh_port=s' => \$ssh_port,
     'use_file' => \$use_file,
 );
@@ -33,5 +34,5 @@
 exit(20) unless GetOptions(%opts);
 
-gateway_lib::read_config(gateway_lib::emulab_config_filename(), \%opts)
+gateway_lib::read_config(gateway_lib::config_filename(), \%opts)
     if $use_file;
 
@@ -56,8 +57,8 @@
 	    my ($iface, $addr) = ($1, $2);
 
-	    my $cmd = "$ssh -w $ifnum:$ifnum -o \"Tunnel ethernet\" " . 
-		"-o \"StrictHostKeyChecking no\" -i $ssh_privkey " .
-		"$peer perl -I$fedkit_dir/lib $fedkit_dir/bin/setup_bridge.pl " .
-		"--tapno=$ifnum --dest=$addr &";
+	    my $cmd = "$ssh -w $ifnum:$ifnum -p $ssh_port " . 
+		"-o \"Tunnel ethernet\" -o \"StrictHostKeyChecking no\" " .
+		"-i $ssh_privkey $peer perl -I$fedkit_dir/lib ".
+		"$fedkit_dir/bin/setup_bridge.pl --tapno=$ifnum --dest=$addr &";
 	    system($cmd);
 	    die if $?;
Index: fedkit/combo.pl
===================================================================
--- fedkit/combo.pl	(revision 37f6592eb7f1f642a95968caad9b140737250a02)
+++ fedkit/combo.pl	(revision f8fa72ba913bb6209f71fb3ea1dafb371d25a87b)
@@ -18,4 +18,5 @@
 my $iface_file = "/var/emulab/boot/ifmap";
 my $ssh = "/usr/bin/ssh";
+my $ssh_port = 22;
 my @ports;
 my $use_file;
@@ -32,4 +33,5 @@
     'port=s' => \@ports,
     'active' => \$active, 
+    'ssh_port=s' => \$ssh_port,
     'use_file' => \$use_file,
 );
@@ -37,6 +39,7 @@
 exit(20) unless GetOptions(%opts);
 
-gateway_lib::read_config(gateway_lib::emulab_config_filename(), \%opts)
-    if $use_file;
+if ($use_file) {
+    gateway_lib::read_config(gateway_lib::config_filename(), \%opts)
+}
 
 my $tunnelparam = $tunnelip ? '--tunnelip' : '';
@@ -50,5 +53,5 @@
 	"--peer=$peer --ssh_pubkey=$ssh_pubkey --ssh_privkey=$ssh_privkey " .
 	" $tunnelparam --fedkit=$fedkit_dir --perl=$perl " .
-	"--ssh=$ssh --interfaces=$iface_file");
+	"--ssh_port=$ssh_port --ssh=$ssh --interfaces=$iface_file");
     exit(20) if $?;
 
Index: fedkit/federate.pl
===================================================================
--- fedkit/federate.pl	(revision 37f6592eb7f1f642a95968caad9b140737250a02)
+++ fedkit/federate.pl	(revision f8fa72ba913bb6209f71fb3ea1dafb371d25a87b)
@@ -3,4 +3,6 @@
 
 use strict;
+
+use Getopt::Long;
 
 use IO::File;
@@ -29,6 +31,9 @@
 my $exp;
 my $proj;
+my $install_smb;
 chomp (my $uname = `uname`);
 my $smbmount = "smbmount.$uname.pl";
+
+GetOptions("install_samba" => \$install_smb);
 
 # find perl
@@ -41,20 +46,36 @@
 $perl = "perl" unless $perl;
 
+if ($install_smb) {
+    # fix yum.conf
+    copy("/etc/yum.conf", "/etc/yum.conf.bak");
+    my $from = new IO::File("/etc/yum.conf.bak");
+    my $to = new IO::File(">/etc/yum.conf");
+    while (<$from>) {
+	s/download.fedoralegacy.org/fedoralegacy.lsu.edu/g;
+	print $to $_;
+    }
+    $from->close();
+    $to->close();
+    # Now, bridging
+    system('/usr/bin/yum -y install samba-client');
+}
 
-$tmcc_p->reader("$TMCC -b status");
-while (<$tmcc_p>) {
-    /ALLOCATED=([^\/]+)\/(\S+)/ && do {
-	($proj, $exp) = ($1, $2);
-	$shared_config_dir = "/proj/$proj/exp/$exp/tmp";
-	last;
-    };
-}
-$tmcc_p->close();
+if (!-e "$local_config_dir/client.conf" ) {
+    $tmcc_p->reader("$TMCC -b status");
+    while (<$tmcc_p>) {
+	/ALLOCATED=([^\/]+)\/(\S+)/ && do {
+	    ($proj, $exp) = ($1, $2);
+	    $shared_config_dir = "/proj/$proj/exp/$exp/tmp";
+	    last;
+	};
+    }
+    $tmcc_p->close();
 
-mkdir($local_config_dir);
+    mkdir($local_config_dir);
 
-foreach my $fn ("seer.conf", "client.conf", "userconf") {
-    copy("$shared_config_dir/$fn", $local_config_dir )
-	if -e "$shared_config_dir/$fn";
+    foreach my $fn ("seer.conf", "client.conf", "userconf", "hosts") {
+	copy("$shared_config_dir/$fn", $local_config_dir )
+	    if -e "$shared_config_dir/$fn";
+    }
 }
 
@@ -72,6 +93,6 @@
 my $hosts = new IO::File("/etc/hosts") || die "Can't open /etc/hosts:$!\n";
 my $new_hosts = new IO::File(">/tmp/hosts") || die "Can't open /tmp/hosts:$!\n";
-my $config_hosts = new IO::File("$shared_config_dir/hosts") || 
-    die "Can't open $shared_config_dir/hosts: $!\n";
+my $config_hosts = new IO::File("$local_config_dir/hosts") || 
+    die "Can't open $local_config_dir/hosts: $!\n";
 my $has_control = 0;
 
@@ -112,14 +133,16 @@
 
 if ($services{'userconfig'}) {
-    $tmcc_p = new IO::Pipe() || die "Can't open pipe for accounts:$!\n";
-    my $old_accounts = new IO::File(">$local_config_dir/old_accts") || 
-	die "Can't open $local_config_dir/old_accts: $!\n";
+    if (!-e "$local_config_dir/old_accts") {
+	$tmcc_p = new IO::Pipe() || die "Can't open pipe for accounts:$!\n";
+	my $old_accounts = new IO::File(">$local_config_dir/old_accts") || 
+	    die "Can't open $local_config_dir/old_accts: $!\n";
 
-    $tmcc_p->reader("$TMCC -b accounts");
-    while (<$tmcc_p>) {
-	print $old_accounts $_;
+	$tmcc_p->reader("$TMCC -b accounts");
+	while (<$tmcc_p>) {
+	    print $old_accounts $_;
+	}
+	$tmcc_p->close();
+	$old_accounts->close();
     }
-    $tmcc_p->close();
-    $old_accounts->close();
     print("Updating accounts");
     system("/usr/local/federation/bin/rc.fedaccounts");
Index: fedkit/gateway_lib.pm
===================================================================
--- fedkit/gateway_lib.pm	(revision 37f6592eb7f1f642a95968caad9b140737250a02)
+++ fedkit/gateway_lib.pm	(revision f8fa72ba913bb6209f71fb3ea1dafb371d25a87b)
@@ -27,4 +27,8 @@
 my $FINDIF = "/usr/local/etc/emulab/findif";
 my $TMCC = "/usr/local/etc/emulab/tmcc";
+
+# Linux choices
+my $BRCTL = "/usr/sbin/brctl";
+my $IPROUTE = "/sbin/ip route ";
 
 # Takes an ssh config file and a reference to a hash of keys whose values must
@@ -176,15 +180,32 @@
     }
 
-    system("ifconfig $bridge create");
-    warn "Cannot create bridge: $?\n" if $?;
-    foreach my $a (@addr) {
-	system("ifconfig $iface delete $a");
-	warn "Cannot delete address $a: $?\n" if $?;
-    }
-    system("ifconfig $bridge addm $iface up");
-    warn "Cannot add intefrace $iface to bridge: $?\n" if $?;
-    system("ifconfig $bridge addm $tap");
-    warn "Cannot add intefrace $tap to bridge: $?\n" if $?;
-    return $?;
+    my $uname = `uname`;
+    chomp $uname;
+
+    if ($uname =~ /FreeBSD/) {
+	system("ifconfig $bridge create");
+	warn "Cannot create bridge: $?\n" if $?;
+	foreach my $a (@addr) {
+	    system("ifconfig $iface delete $a");
+	    warn "Cannot delete address $a: $?\n" if $?;
+	}
+	system("ifconfig $bridge addm $iface up");
+	warn "Cannot add intefrace $iface to bridge: $?\n" if $?;
+	system("ifconfig $bridge addm $tap");
+	warn "Cannot add intefrace $tap to bridge: $?\n" if $?;
+	return $?;
+    }
+    elsif ($uname =~ /Linux/) {
+	system("$IFCONFIG $iface 0.0.0.0 down");
+	system("$BRCTL addbr $bridge");
+	warn "Cannot create bridge: $?\n" if $?;
+	system("$BRCTL addif $bridge $tap");
+	system("$BRCTL addif $bridge $iface");
+	system("$BRCTL stp $bridge off");
+	system("$IFCONFIG $bridge up");
+	system("$IFCONFIG $tap up");
+	system("$IFCONFIG $iface up");
+	return $?;
+    }
 }
 
@@ -194,8 +215,15 @@
     my $ipipe = new IO::Pipe() || die "Can't create pipe for ifconfig: $!\n";
     my @addr;
+    my $uname = `uname`;
+    my $ipre = "inet\\s+([0-9\\.]+)";
+    chomp $uname;
+
+    if ($uname =~ /Linux/) {
+	$ipre = "inet\\s+addr:\\s*([0-9\\.]+)";
+    }
 
     $ipipe->reader("$IFCONFIG $iface");
     while(<$ipipe>) {
-	/inet\s+([0-9\.]+)/ && push(@addr, $1);
+	/$ipre/ && push(@addr, $1);
     }
     $ipipe->close();
@@ -207,10 +235,26 @@
     my($dest) =@_;
     my $rpipe = new IO::Pipe() || die "Can't create pipe for route: $!\n";
-
-    $rpipe->reader("$ROUTE get $dest");
+    my $uname = `uname`;
+    chomp $uname;
+    my $route;
+    my $dev_re;
+
+    if ($uname =~ /Linux/) {
+	$route = $IPROUTE;
+	$dev_re = "\\s+dev\\s+(\\S+)";
+    }
+    elsif ($uname =~ /FreeBSD/) {
+	$route = $ROUTE;
+	$dev_re = 'interface:\\s*([[:alnum:]]+)';
+    }
+
+
+    print "$route get $dest\n";
+    $rpipe->reader("$route get $dest");
     while (<$rpipe>) {
-	/interface:\s*([[:alnum:]]+)/ && do {
+	/$dev_re/ && do {
 	    my $iface = $1;
 	    $rpipe->close();
+	    print "matched: $iface\n";
 	    return $iface;
 	};
@@ -290,10 +334,18 @@
 
 
-sub emulab_config_filename {
-    # Find the configuration file in the usual place, which depends on what
-    # experiment and project we're in.
+sub config_filename {
+    # Find the configuration file in the usual places, if there is one in
+    # /usr/local/federation/etc, use it, otherwise look in the emulab standard
+    # filesystems which depends on what experiment and project we're in.
     my $pid;
     my $eid;
     my $filename;
+    my $fed_dir = "/usr/local/federation/etc/";
+    my $hn = `hostname`;
+    chomp $hn;
+    $hn =~ s/\..*//;
+
+    return "$fed_dir/$hn.gw.conf" if -r "$fed_dir/$hn.gw.conf";
+
     my $tmcd = new IO::Pipe() || die "Can't create pipe: $!\n";
 
@@ -308,7 +360,4 @@
     }
     $tmcd->close();
-    my $hn = `hostname`;
-    chomp $hn;
-    $hn =~ s/\..*//;
     $filename = "/proj/$pid/exp/$eid/tmp/$hn.gw.conf"
 	if $pid and $eid;
@@ -316,4 +365,5 @@
     return $filename;
 }
+
 
 sub wait_for_port {
Index: fedkit/prep_gateway.pl
===================================================================
--- fedkit/prep_gateway.pl	(revision 37f6592eb7f1f642a95968caad9b140737250a02)
+++ fedkit/prep_gateway.pl	(revision f8fa72ba913bb6209f71fb3ea1dafb371d25a87b)
@@ -6,4 +6,6 @@
 
 use Getopt::Long;
+use File::Copy;
+use IO::File;
 
 my $ssh_pubkey;
@@ -20,19 +22,51 @@
 exit(20) unless GetOptions(%opts);
 
-gateway_lib::read_config(gateway_lib::emulab_config_filename(), \%opts)
-    if $use_file;
+if ($use_file) {
+    gateway_lib::read_config(gateway_lib::config_filename(), \%opts)
+}
 
-gateway_lib::set_sshd_params( 
-    { 'GatewayPorts' => 'yes', 'PermitTunnel' => 'yes' } );
-system("/etc/rc.d/sshd restart");
+my $uname = `uname`;
+chomp $uname;
 
-gateway_lib::import_key($ssh_pubkey,'/root/.ssh/authorized_keys')
-    if $ssh_pubkey;
+if ($uname =~ /Linux/) {
+    # Right now the only gateway nodes that are Linux nodes are ProtoGENI
+    # nodes.  They need a bunch of custom updates to get into the 21st century,
+    # but they are on the network.
+    if ( -x '/usr/local/federation/bin/sshd' && 
+	    -e '/usr/local/federation/etc/sshd_config') {
+	# Start our modern sshd if one is there
+	system("/usr/local/federation/bin/sshd -p 20200 -f " .
+	    "/usr/local/federation/etc/sshd_config");
+    }
+    # fix yum.conf
+    copy("/etc/yum.conf", "/etc/yum.conf.bak");
+    my $from = new IO::File("/etc/yum.conf.bak");
+    my $to = new IO::File(">/etc/yum.conf");
+    while (<$from>) {
+	s/download.fedoralegacy.org/fedoralegacy.lsu.edu/g;
+	print $to $_;
+    }
+    $from->close();
+    $to->close();
+    # Now, bridging
+    system('/usr/bin/yum -y install bridge-utils');
+    #and keys
+    gateway_lib::import_key($ssh_pubkey,'/root/.ssh/authorized_keys')
+	if $ssh_pubkey;
+}
+elsif ($uname =~ /FreeBSD/ ){
+    gateway_lib::set_sshd_params( 
+	{ 'GatewayPorts' => 'yes', 'PermitTunnel' => 'yes' } );
+    system("/etc/rc.d/sshd restart");
 
-# Need these to make the Ethernet tap and bridge work.
-system("kldload /boot/kernel/bridgestp.ko") 
-    if -r "/boot/kernel/bridgestp.ko"; 
-system("kldload /boot/kernel/if_bridge.ko");
-system("kldload /boot/kernel/if_tap.ko");
+    gateway_lib::import_key($ssh_pubkey,'/root/.ssh/authorized_keys')
+	if $ssh_pubkey;
+
+    # Need these to make the Ethernet tap and bridge work.
+    system("kldload /boot/kernel/bridgestp.ko") 
+	if -r "/boot/kernel/bridgestp.ko"; 
+    system("kldload /boot/kernel/if_bridge.ko");
+    system("kldload /boot/kernel/if_tap.ko");
+}
 
 if ( $tunnelip ) {
