Commit 6a26b246 authored by Mike Hibler's avatar Mike Hibler

Further overhaul of firewall code. NOTE: required bump of tmcd version to 34.

Firewalls now work with nodes which require a subboss. Had to introduce new
firewall rules which skipped around the checks that no packets to/from
node control net IPs should pass through the firewall, if the IP in question
belongs to a subboss (since subboss is on the node control network). It
actually checks for all Emulab servers (boss, ops, fs or any subboss),
so the code should work for an Emulab install which has a non-segmented
control network in which all servers were in the same subnet as the nodes.

In addition to the new rules, we also had to pass in additional information
via "tmcc firewallinfo" giving the IP/MAC of those server nodes that are on
the node control network. We use this to establish ARP entries on the
inside network so that nodes can find the servers. Since the existing
client-side firewall code in libsetup.pm would blow up if it got a line
that it didn't recognize, I had to bump the tmcd version number and add
some conditional code to tmcd.c:dofwinfo() to not return the extra info for
old versions.

Added a couple of new firewall variables EMULAB_BOSSES and EMULAB_SERVERS
that are used in the new rules. Fixed the support scripts in firewall/
to properly initialize these variables.

IMPORTANT: tmcd looks up boss, ops, fs, and subbosses in the interfaces
table to find their IPs and MAC addresses. By default, we do not create
such interface table entries for boss/ops/fs. We have them at Utah for
other reasons. These entries are only needed if you have a non-segmented
control network (or a subboss) and you want to firewall such nodes.
The script to initialize the firewall variables (initfwvars.pl) will
print out a warning for configurations that are affected and don't have
the entries.
parent ba9e4929
......@@ -24,6 +24,9 @@
*
* Note, this is assumed to be an integer. No need for 3.23.479 ...
* NB: See ron/libsetup.pm. That is version 4! I'll merge that in.
*
* IMPORTANT NOTE: if you change CURRENT_VERSION, you must also change
* it in clientside/tmcc/common/libsetup.pm!
*/
#define DEFAULT_VERSION 2
#define CURRENT_VERSION 33
#define CURRENT_VERSION 34
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2004, 2005 University of Utah and the Flux Group.
# Copyright (c) 2004-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -144,6 +144,10 @@ sub doboot()
$rc = firewaller();
last SWITCH;
};
/^ipchains$/i && do {
$rc = firewaller();
last SWITCH;
};
/^remote$/i && do {
last SWITCH;
};
......
......@@ -58,7 +58,10 @@ use librc;
#
# BE SURE TO BUMP THIS AS INCOMPATIBILE CHANGES TO TMCD ARE MADE!
#
sub TMCD_VERSION() { 33; };
# IMPORTANT NOTE: if you change the version here, you must also change it
# in clientside/lib/tmcd/tmcd.h!
#
sub TMCD_VERSION() { 34; };
libtmcc::configtmcc("version", TMCD_VERSION());
# Control tmcc timeout.
......@@ -2134,6 +2137,45 @@ sub forcecopy($$)
my %fwvars = ();
#
# Not pretty, but...
#
sub insubnet($$)
{
my ($netspec,$addr) = @_;
my ($net,$mask);
my @NETMASKS = (
0x10000000, # 0
0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, # 1 - 4
0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, # 5 - 8
0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, # 9 - 12
0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, # 13 - 16
0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, # 17 - 20
0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, # 21 - 24
0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, # 25 - 28
0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF # 29 - 32
);
if ($netspec =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/) {
return 0
if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255 || $5 > 32);
$mask = $NETMASKS[$5];
$net = (($1 << 24) | ($2 << 16) | ($3 << 8) | $4);
$net &= $mask;
} else {
return 0;
}
if ($addr =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
return 0
if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255);
$addr = (($1 << 24) | ($2 << 16) | ($3 << 8) | $4);
$addr &= $mask;
}
return ($addr == $net);
}
#
# Substitute values of variables in a firewall rule.
#
......@@ -2167,6 +2209,7 @@ sub getfwconfig($$;$)
my @fwrules = ();
my @fwhosts = ();
my %fwhostmacs = ();
my %fwsrvmacs = ();
$$infoptr = undef;
@$rptr = ();
......@@ -2180,6 +2223,7 @@ sub getfwconfig($$;$)
my $rpat = q(RULENO=(\d*) RULE="(.*)");
my $vpat = q(VAR=(EMULAB_\w+) VALUE="(.*)");
my $hpat = q(HOST=([-\w]+) CNETIP=([\d\.]*) CNETMAC=([\da-f]{12}));
my $spat = q(SERVER=([-\w]+) CNETIP=([\d\.]*) CNETMAC=([\da-f]{12}));
my $lpat = q(LOG=([\w,]+));
$fwinfo->{"TYPE"} = "none";
......@@ -2237,6 +2281,17 @@ sub getfwconfig($$;$)
# and save off the MACs
$fwhostmacs{$host} = $mac;
} elsif ($line =~ /$spat/) {
my $srv = $1;
my $ip = $2;
my $mac = $3;
#
# Save off the MACs. Note that since we hash by IP address
# we get a unique set of nodes. This is desirable for setups
# where, e.g., ops == fs.
#
$fwsrvmacs{$ip} = $mac;
} elsif ($line =~ /$lpat/) {
for my $log (split(',', $1)) {
if ($log =~ /^allow|accept$/) {
......@@ -2248,23 +2303,66 @@ sub getfwconfig($$;$)
}
}
} else {
#
# This used to be fatal. But having unexpected input lines blow
# up the firewall is probably worse than ignoring the lines.
# And it requires that we bump the tmcd version number and
# conditionalize tmcd when we add new line types (which I had
# to do when I added server lines).
#
warn("*** WARNING: Bad firewall info line: $line\n");
return 1;
}
}
# XXX inner elab: make sure we have a "myfs" entry
if (defined($fwhostmacs{"myboss"}) && !defined($fwhostmacs{"myfs"})) {
for my $host (@fwhosts) {
if ($host =~ /NAME=myops/) {
$host =~ s/ALIASES=''/ALIASES='myfs'/;
#
# XXX inner elab: make sure we have "myops" and "myfs" entries.
#
# If there is no myops we are doing ops-as-a-jail. Here we alias both
# myops and myfs to myboss; not right, but good enough.
#
# If just myfs is not defined, then ops is the file server and we
# alias myfs to myops.
#
if (defined($fwhostmacs{"myboss"})) {
if (!defined($fwhostmacs{"myops"})) {
for my $host (@fwhosts) {
if ($host =~ /NAME=myboss/) {
$host =~ s/ALIASES=''/ALIASES='myops,myfs'/;
}
}
} elsif (!defined($fwhostmacs{"myfs"})) {
for my $host (@fwhosts) {
if ($host =~ /NAME=myops/) {
$host =~ s/ALIASES=''/ALIASES='myfs'/;
}
}
}
}
# info for proxy ARP
$fwinfo->{"GWIP"} = $fwvars{"EMULAB_GWIP"};
$fwinfo->{"GWMAC"} = $fwvars{"EMULAB_GWMAC"};
# merge GW info into fwsrvmacs hash
$fwsrvmacs{$fwvars{"EMULAB_GWIP"}} = $fwvars{"EMULAB_GWMAC"};
$fwsrvmacs{$fwvars{"EMULAB_GWIP"}} =~ s/://g;
# info for proxy ARP, to publish inside...
if (%fwsrvmacs) {
#
# Prune out any that are not on the EMULAB_CNET.
#
if (!exists($fwvars{"EMULAB_CNET"})) {
$fwinfo->{"SRVMACS"} = \%fwsrvmacs;
} else {
my %lsrv = ();
foreach my $ip (keys %fwsrvmacs) {
if (insubnet($fwvars{"EMULAB_CNET"}, $ip)) {
$lsrv{$ip} = $fwsrvmacs{$ip};
}
}
if (%lsrv) {
$fwinfo->{"SRVMACS"} = \%lsrv;
}
}
}
# ...and outside.
if (%fwhostmacs) {
$fwinfo->{"MACS"} = \%fwhostmacs;
}
......
......@@ -664,6 +664,11 @@ sub os_fwconfig_line($@)
my ($fwinfo, @fwrules) = @_;
my ($upline, $downline);
if ($fwinfo->{TYPE} ne "ipfw" && $fwinfo->{TYPE} ne "ipfw2-vlan") {
warn "*** WARNING: unsupported firewall type '", $fwinfo->{TYPE}, "'\n";
return ("false", "false");
}
# XXX debugging
my $logaccept = defined($fwinfo->{LOGACCEPT}) ? $fwinfo->{LOGACCEPT} : 0;
my $logreject = defined($fwinfo->{LOGREJECT}) ? $fwinfo->{LOGREJECT} : 0;
......@@ -683,6 +688,17 @@ sub os_fwconfig_line($@)
return ("false", "false");
}
}
$href = $fwinfo->{SRVMACS};
while (my ($node,$mac) = each(%$href)) {
if ($mac eq $fwinfo->{OUT_IF}) {
delete($$href{$node});
} elsif ($mac =~ /^(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})$/) {
$$href{$node} = "$1:$2:$3:$4:$5:$6";
} else {
warn "*** WARNING: Bad MAC returned for $node in fwinfo: $mac\n";
return ("false", "false");
}
}
#
# VLAN enforced layer2 firewall with FreeBSD/IPFW2
......@@ -732,9 +748,14 @@ sub os_fwconfig_line($@)
$upline .=
" ifconfig $vlandev inet $myip netmask $mymask rtabid 2\n";
# provide GW MAC to inside
$upline .= " arp -r 2 -s " .
$fwinfo->{GWIP} . " " . $fwinfo->{GWMAC} . " pub only\n";
# publish servers (including GW) on inside and for us on outside
if (defined($fwinfo->{SRVMACS})) {
my $href = $fwinfo->{SRVMACS};
while (my ($ip,$mac) = each %$href) {
$upline .= " arp -r 2 -s $ip $mac pub only\n";
$upline .= " arp -s $ip $mac\n";
}
}
# provide node MACs to outside, and unpublished on inside for us
my $href = $fwinfo->{MACS};
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -9,6 +9,7 @@ TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ..
SUBDIR = firewall
TBDB = @TBDBNAME@
MDOPTS = --compact --skip-extended-insert --no-create-info --skip-set-charset
FW_SCRIPTS = initfwvars.pl
FW_FILES = open.sql closed.sql basic.sql elabinelab.sql
......@@ -27,7 +28,7 @@ include $(TESTBED_SRCDIR)/GNUmakerules
$(SRCDIR)/genconfig.pl -f $(SRCDIR)/fw-rules -M $* > $@
insertvars: initfwvars.pl
@if ! `mysqldump $(TBDB) default_firewall_vars >/dev/null 2>&1`; then \
@if ! `mysqldump $(MDOPTS) $(TBDB) default_firewall_vars >vars.old`; then \
echo -n '*** default_firewall_vars table does not exist, '; \
echo 'see sql/database-migrate.txt'; \
exit 1; \
......@@ -37,10 +38,11 @@ insertvars: initfwvars.pl
fi
insertrules: $(FW_FILES)
@if ! `mysqldump $(TBDB) default_firewall_rules >/dev/null 2>&1`; then \
@if ! `mysqldump $(MDOPTS) -w "1 order by type,style,ruleno" $(TBDB) default_firewall_rules >rules.old`; then \
echo -n '*** default_firewall_rules table does not exist, '; \
echo 'see sql/database-migrate.txt'; \
exit 1; \
else \
cat $(FW_FILES) | mysql $(TBDB); \
echo 'FW rules updated in DB'; \
fi
......@@ -8,8 +8,9 @@
# Firewall rule template.
#
# The bulk of the line is the body of an IPFW rule, a '#' denoted "comment"
# at the end of the line indicates a rule number to use, and a comma
# separated list of styles to which the rule applies.
# at the end of the line indicates a rule number to use, a comma separated
# list of styles to which the rule applies, and an optional qualifier that
# indicates the types of firewalled nodes to which the rule should apply.
#
# Styles:
#
......@@ -17,8 +18,15 @@
# CLOSED allows only Emulab infrastructure services
# BASIC CLOSED + ssh from anywhere
# ELABINELAB Elab-in-elab, eliminates many Emulab services
# WINDOWS Rules specific to WinXP, not a real style right now
# these are usually incorporated into the BASIC rules.
#
# Qualifiers:
#
# WINDOWS For nodes running some variant of Windows
# SAMENET For nodes that are on the same subnet as any
# "control" host (boss, subbosses, ops, fs).
#
# Note that currently, we do not support the qualifier. Rules with a
# qualifier are applied unconditionally to the style which they are a part of.
#
# Variables expanded by rc.firewall script that can be used here:
#
......@@ -30,6 +38,8 @@
# EMULAB_BOSSES Comma separated list of subbosses (including "boss"),
# used for services that subbosses provide
# (dhcp/tftp/frisbee).
# EMULAB_SERVERS Comma separated list of all servers
# (EMULAB_BOSSES + "ops" + "fs")
#
# Currently these are sufficient for rules we use. Note that you can
# safely use symbolic hostnames "boss", "ops", "fs", "users", "ntp1"
......@@ -220,7 +230,21 @@ deny not mac-type ip # 80: BASIC,CLOSED,ELABINELAB
# (due to the helper function).
# so for now we allow any IP traffic from the gateway.
#
allow ip from EMULAB_GWIP to any in not via vlan0 # 83: CLOSED,ELABINELAB
allow ip from EMULAB_GWIP to any in not via vlan0 # 81: CLOSED,ELABINELAB
#
# XXX yuk 2! In a non-segmented control network or in a configuration with
# subbosses, some or all of the server machines will be a part of "the node
# control net" so we cannot unconditionally block all traffic to/from outside
# control net addresses. Here we allow through all traffic involving the known
# servers and let later rules further limit it.
#
skipto 90 ip from EMULAB_SERVERS to any in not via vlan0 # 82: CLOSED,ELABINELAB+SAMENET
skipto 90 ip from any to EMULAB_SERVERS in via vlan0 # 83: CLOSED,ELABINELAB+SAMENET
#
# Otherwise, nodes inside/outside of the firewall cannot talk to each other.
#
deny ip from any to EMULAB_CNET in via vlan0 # 84: CLOSED,ELABINELAB
deny ip from EMULAB_CNET to any in not via vlan0 # 85: CLOSED,ELABINELAB
......@@ -230,7 +254,7 @@ deny ip from EMULAB_CNET to any in not via vlan0 # 85: CLOSED,ELABINELAB
# Beyond this rule we no longer have to check to make sure that source
# hosts like "boss" and "ops" come in the correct interface.
#
deny ip from not 0.0.0.0,255.255.255.255,EMULAB_CNET to any in via vlan0 # 88: BASIC,CLOSED,ELABINELAB
deny ip from not 0.0.0.0,255.255.255.255,EMULAB_CNET to any in via vlan0 # 90: BASIC,CLOSED,ELABINELAB
#
# By convention, user supplied rules are in the 100-60000 range
......@@ -300,8 +324,10 @@ allow tcp from any to myboss 3069 in not recv vlan0 setup keep-state # 60044:
#
# Frisbee master server from boss
# elabinelab: boss to myboss
#
allow tcp from any to EMULAB_BOSSES 64494 in via vlan0 setup keep-state # 60045: BASIC,CLOSED
allow tcp from myboss to EMULAB_BOSSES 64494 in via vlan0 setup keep-state # 60045: ELABINELAB
#
# Frisbee multicast with boss
......@@ -343,16 +369,16 @@ allow icmp from any to boss icmptypes 0 # 60051: CLOSED,ELABINELAB
# SMB (445) with fs
# rdesktop (3389) to nodes
#
allow tcp from any to any 80,443 in via vlan0 setup keep-state # 60056: WINDOWS,BASIC
allow tcp from any to fs 445 in via vlan0 setup keep-state # 60057: WINDOWS,BASIC
allow tcp from any not 0-1023 to any 3389 in not recv vlan0 setup keep-state # 60059: WINDOWS,BASIC
allow tcp from any to any 80,443 in via vlan0 setup keep-state # 60056: BASIC+WINDOWS
allow tcp from any to fs 445 in via vlan0 setup keep-state # 60057: BASIC+WINDOWS
allow tcp from any not 0-1023 to any 3389 in not recv vlan0 setup keep-state # 60059: BASIC+WINDOWS
#
# Windows
# Explicitly stop blaster (135,4444) and slammer (1434)
#
deny tcp from any to any 135,4444 # 60060: WINDOWS
deny udp from any to any 1434 # 60061: WINDOWS
deny tcp from any to any 135,4444 # 60060: BASIC,CLOSED,ELABINELAB+WINDOWS
deny udp from any to any 1434 # 60061: BASIC,CLOSED,ELABINELAB+WINDOWS
# Boot time only services (DHCP, TFTP, bootinfo, TMCC).
......@@ -361,13 +387,21 @@ deny udp from any to any 1434 # 60061: WINDOWS
allow udp from any 68 to 255.255.255.255 67 recv vlan0 # 60064: BASIC,CLOSED,ELABINELAB
allow udp from any 67 to any 68 in not recv vlan0 # 60065: BASIC,CLOSED,ELABINELAB
#
# TFTP with boss or ops
# XXX tftpd can pick any port it wants in response to a request from any port
# so we have to open wide
# so we have to open wide.
#
# Note that for elabinelab, inside nodes still need to be able to talk to
# real boss for PXE boot.
#
allow udp from any to EMULAB_BOSSES,ops 69 keep-state # 60066: BASIC,CLOSED,ELABINELAB
allow udp from EMULAB_BOSSES,ops not 0-1023 to any not 0-1023 keep-state # 60067: BASIC,CLOSED,ELABINELAB
# bootinfo with boss (nodes request/receive info or boss does PXEWAKEUP)
#
# Emulab bootinfo with boss (nodes request/receive info or boss does PXEWAKEUP)
# XXX do we really need this for elabinelab inner nodes?
#
allow udp from any 9696 to boss 6969 keep-state # 60068: BASIC,CLOSED,ELABINELAB
allow udp from boss 6970 to any 9696 # 60069: BASIC,CLOSED,ELABINELAB
......
......@@ -13,6 +13,7 @@ my $optlist = "eMIf:";
my $domysql = 0;
my $doipfw = 1;
my $expand = 0;
my $qualifiers = 0;
my @lines;
sub usage()
......@@ -20,6 +21,7 @@ sub usage()
print "Usage: genconfig [-MI] config ...\n".
" -e expand EMULAB_ variables\n".
" -f file specify the input rules file\n".
" -q include qualifiers\n".
" -M generate mysql commands\n".
" -I generate IPFW commands\n".
"\n".
......@@ -37,6 +39,7 @@ sub getfwvars()
$fwvars{EMULAB_NS} = "155.98.32.70";
$fwvars{EMULAB_CNET} = "155.98.36.0/22";
$fwvars{EMULAB_BOSSES} = "boss,subboss";
$fwvars{EMULAB_SERVERS} = "boss,subboss,ops";
$fwvars{EMULAB_MCADDR} = "234.0.0.0/8";
$fwvars{EMULAB_MCPORT} = "1025-65535";
}
......@@ -89,15 +92,28 @@ sub doconfig($)
} else {
$ruleno++;
}
my $qual;
if ($line =~ /#.*\+(\w+)/) {
$qual = $1;
}
($rule = $line) =~ s/\s*#.*//;
chomp($rule);
$rule = expandfwvars($rule) if ($expand);
if ($doipfw) {
print "ipfw add $ruleno $rule\n";
print "ipfw add $ruleno $rule # config=$config";
print ", $qual only)"
if ($qualifiers && $qual);
print "\n";
}
if ($domysql) {
print "INSERT INTO `default_firewall_rules` VALUES (".
"'$type','$style',$enabled,$ruleno,'$rule');\n";
if ($qualifiers) {
print "INSERT INTO `default_firewall_rules` VALUES (".
"'$type','$style',$enabled,$qual,$ruleno,'$rule');\n";
} else {
print "INSERT INTO `default_firewall_rules` VALUES (".
"'$type','$style',$enabled,$ruleno,'$rule');\n";
}
}
}
......@@ -122,6 +138,9 @@ if (defined($options{"e"})) {
if (defined($options{"f"})) {
$datafile = $options{"f"};
}
if (defined($options{"q"})) {
$qualifiers = 1;
}
if (@ARGV == 0) {
usage();
......
......@@ -21,7 +21,13 @@ use libdb;
my $CONTROL_NETWORK = "@CONTROL_NETWORK@";
my $CONTROL_NETMASK = "@CONTROL_NETMASK@";
my $PRIVATE_NETWORK = "@PRIVATE_NETWORK@";
my $PRIVATE_NETMASK = "@PRIVATE_NETMASK@";
my $PUBLIC_NETWORK = "@PUBLIC_NETWORK@";
my $PUBLIC_NETMASK = "@PUBLIC_NETMASK@";
my $BOSSNODE_IP = "@BOSSNODE_IP@";
my $USERNODE_IP = "@USERNODE_IP@";
my $FSNODE_IP = "@FSNODE_IP@";
my $FRISBEE_MCASTADDR = "@FRISEBEEMCASTADDR@";
my $FRISBEE_MCASTPORT = "@FRISEBEEMCASTPORT@";
......@@ -55,14 +61,52 @@ for (my $i = 0; $i < scalar(@NETMASKS); $i++) {
}
my $str;
my $res;
# By default there is only "boss"
$str = "replace into default_firewall_vars values ('EMULAB_BOSSES', 'boss')";
#
# Create EMULAB_BOSSES variable.
#
# There is boss...
my @bosses = "boss";
# ...and any subbosses
$res = DBQueryFatal("select distinct subboss_id from subbosses");
while (my ($sb) = $res->fetchrow_array()) {
push(@bosses, $sb)
if ($sb);
}
my $bstr = join(',', @bosses);
$str = "replace into default_firewall_vars values ('EMULAB_BOSSES', '$bstr')";
print "$str\n"
if (!$doit);
DBQueryFatal($str)
if ($doit);
#
# Create EMULAB_SERVERS variable
#
# Start with bosses...
my @servers = @bosses;
# ...add ops...
push(@servers, "ops");
# ...and fs if it exists
if ($FSNODE_IP ne $USERNODE_IP) {
push(@servers, "fs");
}
my $sstr = join(',', @servers);
$str = "replace into default_firewall_vars values ('EMULAB_SERVERS', '$sstr')";
print "$str\n"
if (!$doit);
DBQueryFatal($str)
if ($doit);
#
# Create EMULAB_NS variable
#
# Use boss IP as "ns" since that is what we assume everywhere else
$str = "replace into default_firewall_vars values ('EMULAB_NS', '$BOSSNODE_IP')";
print "$str\n"
......@@ -70,6 +114,10 @@ print "$str\n"
DBQueryFatal($str)
if ($doit);
#
# Create EMULAB_CNET variable
#
# Add the control net in CIDR notation
$str = "replace into default_firewall_vars values ('EMULAB_CNET', '$CONTROL_NETWORK/$CIDRMASK')";
print "$str\n"
......@@ -77,6 +125,10 @@ print "$str\n"
DBQueryFatal($str)
if ($doit);
#
# Create EMULAB_MCADDR and EMULAB_MCPORT variables
#
#
# Frisbee multicast info
# XXX assumptions, assumptions (as of 9/05). We could allow up to a /8 network
......@@ -85,9 +137,15 @@ DBQueryFatal($str)
# XXX assumptions II (as of 2/08). frisbeelauncher ticks up the MC address
# all the way to /8 (it wraps the port number as needed), so lets make it
# so here.
# XXX assumptions III (as of 11/11). Frisbee master server running on
# subboss can open up the port range even wider, by default starting at 1025.
#
my @mcaddr = split /\./, $FRISBEE_MCASTADDR, 4;
$FRISBEE_MCASTADDR = $mcaddr[0] . ".0.0.0/8";
if ($bstr ne "boss") {
$FRISBEE_MCASTPORT = 1025
if ($FRISBEE_MCASTPORT > 1025);
}
$FRISBEE_MCASTPORT = $FRISBEE_MCASTPORT . "-65535";
$str = "replace into default_firewall_vars values ('EMULAB_MCADDR', '$FRISBEE_MCASTADDR')";
......@@ -102,4 +160,34 @@ print "$str\n"
DBQueryFatal($str)
if ($doit);
#
# Check for support of non-segmented control network.
#
# For this to work, all servers on the same subnet must have entries
# in the interfaces table with a valid MAC address.
#
my $nodenet = inet_aton($CONTROL_NETWORK) & inet_aton($CONTROL_NETMASK);
my $privnet = inet_aton($PRIVATE_NETWORK) & inet_aton($PRIVATE_NETMASK);
my $pubnet = inet_aton($PUBLIC_NETWORK) & inet_aton($PUBLIC_NETMASK);
my $segcnet = 1;
if ($nodenet eq $privnet && $privnet eq $pubnet) {
print "You appear to be using a non-segmented control network.\n";
$segcnet = 0;
}
foreach my $n (@servers) {
my $res = DBQueryFatal("select node_id,IP,mac from interfaces ".
"where role='ctrl' and node_id='$n'");
if ($res->numrows == 0) {
if ($segcnet) {
print STDERR "NOTE: '$n' does not have an interfaces table entry,".
" but this doesn't matter in your config.\n";
} else {
print STDERR "WARNING: '$n' does not have an interfaces table entry,".
" you will need to create one for the control net interface.\n";
}
}
}
exit(0);
......@@ -7939,6 +7939,55 @@ COMMAND_PROTOTYPE(dofwinfo)
info("FWINFO: %d firewalled hosts\n", nrows);
}
/*
* We also start returning the MAC addresses for boss, ops, fs
* and subboss servers so that we can create ARP entries. This is
* necessary if the servers are in the same subnet as the nodes
* and thus the gateway is not used to contact them.
*/
if (vers > 33) {
res = mydb_query("select node_id,IP,mac from interfaces "
"where role='ctrl' and node_id in "
"('boss','ops','fs',"
"(select distinct subboss_id from subbosses))",
3);
if (!res) {
error("FWINFO: %s: DB Error getting server info!\n",
reqp->nodeid);
return 1;
}
nrows = (int)mysql_num_rows(res);
if (nrows > 0) {
struct in_addr cnet, cmask, naddr;
inet_aton(CONTROL_NETWORK, &cnet);
inet_aton(CONTROL_NETMASK, &cmask);
cnet.s_addr &= cmask.s_addr;
for (n = nrows; n > 0; n--) {
row = mysql_fetch_row(res);
/*
* Return the ones on the node control net.
*/
inet_aton(row[1], &naddr);
naddr.s_addr &= cmask.s_addr;
if (naddr.s_addr != cnet.s_addr)
continue;
OUTPUT(buf, sizeof(buf),
"SERVER=%s CNETIP=%s CNETMAC=%s\n",
row[0], row[1], row[2]);
client_writeback(sock, buf, strlen(buf), tcp);
}
}
mysql_free_result(res);
if (verbose)
info("FWINFO: %d server hosts\n", nrows);
}
return 0;
}
......
Markdown is supported
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