Commit c0dcd3b6 authored by Leigh B. Stoller's avatar Leigh B. Stoller

First cut at client side configuration of wireless nodes. Redhat only,

no freebsd support.

The primary change is that tmcd now sends down a list of setting to
apply to each interface, and that list is turned into a hash table,
and provided to rc.config, which passes them along to the machine
dependent routine in liblocsetup.

Then in the linux version of liblocsetup there is a bunch of new code
to configure wireless links using iwconfig and iwpriv, using the
settings array.

All of this is bound to change once we get more experience with it.
parent 69e0a824
......@@ -122,12 +122,14 @@ sub doboot()
foreach my $ifconfig (@ifacelist) {
if (! $ifconfig->{ISVETH}) {
my $inet = $ifconfig->{IPADDR};
my $type = $ifconfig->{TYPE};
my $mask = $ifconfig->{IPMASK};
my $mac = $ifconfig->{MAC};
my $speed = $ifconfig->{SPEED};
my $duplex = $ifconfig->{DUPLEX};
my $aliases = $ifconfig->{ALIASES};
my $iface = $ifconfig->{IFACE};
my $settings = $ifconfig->{SETTINGS};
my $ifrtabid = undef;
#
......@@ -145,7 +147,8 @@ sub doboot()
my ($upline, $downline) =
os_ifconfig_line($iface, $inet, $mask,
$speed, $duplex, $aliases, $ifrtabid);
$speed, $duplex, $aliases,
$type, $settings, $ifrtabid);
$upcmds .= "$upline\n "
if (defined($upline));
......
......@@ -42,7 +42,7 @@ use libtmcc;
#
# BE SURE TO BUMP THIS AS INCOMPATIBILE CHANGES TO TMCD ARE MADE!
#
sub TMCD_VERSION() { 15; };
sub TMCD_VERSION() { 16; };
libtmcc::configtmcc("version", TMCD_VERSION());
# Control tmcc timeout.
......@@ -450,6 +450,7 @@ sub getifconfig($)
my ($rptr) = @_; # Return list to caller (reference).
my @tmccresults = ();
my @ifacelist = (); # To be returned to caller.
my %ifacehash = ();
if (tmcc(TMCCCMD_IFC, undef, \@tmccresults) < 0) {
warn("*** WARNING: Could not get interface config from server!\n");
......@@ -457,17 +458,37 @@ sub getifconfig($)
return -1;
}
my $ethpat = q(IFACETYPE=(\w*) INET=([0-9.]*) MASK=([0-9.]*) MAC=(\w*) );
$ethpat .= q(SPEED=(\w*) DUPLEX=(\w*) IPALIASES="(.*)" IFACE=(\w*) );
$ethpat .= q(RTABID=(\d*));
my $ethpat = q(INTERFACE IFACETYPE=(\w*) INET=([0-9.]*) MASK=([0-9.]*) );
$ethpat .= q(MAC=(\w*) SPEED=(\w*) DUPLEX=(\w*) IPALIASES="(.*)" );
$ethpat .= q(IFACE=(\w*) RTABID=(\d*));
my $vethpat = q(IFACETYPE=(\w*) INET=([0-9.]*) MASK=([0-9.]*) ID=(\d*) );
$vethpat .= q(VMAC=(\w*) PMAC=(\w*) RTABID=(\d*) ENCAPSULATE=(\d*));
my $vethpat = q(INTERFACE IFACETYPE=(\w*) INET=([0-9.]*) MASK=([0-9.]*) );
$vethpat .= q(ID=(\d*) VMAC=(\w*) PMAC=(\w*) RTABID=(\d*) );
$vethpat .= q(ENCAPSULATE=(\d*));
my $setpat = q(INTERFACE_SETTING MAC=(\w*) );
$setpat .= q(KEY='([-\w\.\:]*)' VAL='([-\w\.\:]*)');
foreach my $str (@tmccresults) {
my $ifconfig = {};
if ($str =~ /$ethpat/) {
if ($str =~ /^$setpat/) {
my $mac = $1;
my $capkey = $2;
my $capval = $3;
#
# Stash the setting into the setting list, but must find the
#
if (!exists($ifacehash{$mac})) {
warn("*** WARNING: ".
"Could not map $mac for its interface settings!\n");
next;
}
$ifacehash{$mac}->{"SETTINGS"}->{$capkey} = $capval;
}
elsif ($str =~ /$ethpat/) {
my $ifacetype= $1;
my $inet = $2;
my $mask = $3;
my $mac = $4;
......@@ -485,6 +506,7 @@ sub getifconfig($)
}
$ifconfig->{"ISVETH"} = 0;
$ifconfig->{"TYPE"} = $ifacetype;
$ifconfig->{"IPADDR"} = $inet;
$ifconfig->{"IPMASK"} = $mask;
$ifconfig->{"MAC"} = $mac;
......@@ -493,7 +515,9 @@ sub getifconfig($)
$ifconfig->{"ALIASES"} = $aliases;
$ifconfig->{"IFACE"} = $iface;
$ifconfig->{"RTABID"} = $rtabid;
$ifconfig->{"SETTINGS"} = {};
push(@ifacelist, $ifconfig);
$ifacehash{$mac} = $ifconfig;
}
elsif ($str =~ /$vethpat/) {
my $inet = $2;
......
......@@ -25,4 +25,4 @@
* NB: See ron/libsetup.pm. That is version 4! I'll merge that in.
*/
#define DEFAULT_VERSION 2
#define CURRENT_VERSION 15
#define CURRENT_VERSION 16
......@@ -111,9 +111,10 @@ 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, $rtabid) = @_;
my ($iface, $inet, $mask, $speed, $duplex, $aliases,
$iface_type, $settings, $rtabid) = @_;
my $media = "";
my $mediaopt = "";
my ($uplines, $downlines);
......
......@@ -63,7 +63,8 @@ my $USERDEL = "/usr/sbin/userdel";
my $USERMOD = "/usr/sbin/usermod";
my $GROUPADD = "/usr/sbin/groupadd";
my $GROUPDEL = "/usr/sbin/groupdel";
my $IFCONFIG = "/sbin/ifconfig %s inet %s netmask %s";
my $IFCONFIGBIN = "/sbin/ifconfig";
my $IFCONFIG = "$IFCONFIGBIN %s inet %s netmask %s";
my $IFC_1000MBS = "1000baseTx";
my $IFC_100MBS = "100baseTx";
my $IFC_10MBS = "10baseT";
......@@ -100,10 +101,122 @@ 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, $rtabid) = @_;
my ($ifc, $miirest, $miisleep, $miisetspd, $media);
my ($iface, $inet, $mask, $speed, $duplex, $aliases,
$iface_type, $settings, $rtabid) = @_;
my ($miirest, $miisleep, $miisetspd, $media);
my ($uplines, $downlines);
#
# Special handling for new style interfaces (which have settings).
# This should all move into per-type modules at some point.
#
if (defined($settings) && exists($settings->{"protocol"}) &&
$settings->{"protocol"} ne "ethernet") {
#
# Setting the protocol is special and appears to be card specific.
# How stupid is that!
#
my $protocol = $settings->{"protocol"};
my $privcmd = "";
if ($iface_type eq "ath") {
$privcmd = "/sbin/iwpriv $iface mode ";
SWITCH1: for ($protocol) {
/^80211a$/ && do {
$privcmd .= "1";
last SWITCH1;
};
/^80211b$/ && do {
$privcmd .= "2";
last SWITCH1;
};
/^80211g$/ && do {
$privcmd .= "3";
last SWITCH1;
};
}
}
else {
warn("*** WARNING: Unsupported interface type $iface_type!\n");
return undef;
}
#
# At the moment, we expect just the various flavors of 80211, and
# we treat them all the same, configuring with iwconfig and iwpriv.
#
my $iwcmd = "/sbin/iwconfig $iface ";
#
# We demand to be given an ssid.
#
if (!exists($settings->{"ssid"})) {
warn("*** WARNING: No SSID provided for $iface!\n");
return undef;
}
$iwcmd .= "essid ". $settings->{"ssid"};
# If we do not get a channel, pick one.
if (exists($settings->{"channel"})) {
$iwcmd .= " channel " . $settings->{"channel"};
}
else {
$iwcmd .= " channel 3";
}
# txpower and rate default to auto if not specified.
if (exists($settings->{"rate"})) {
$iwcmd .= " rate " . $settings->{"rate"};
}
else {
$iwcmd .= " rate auto";
}
if (exists($settings->{"txpower"})) {
$iwcmd .= " txpower " . $settings->{"txpower"};
}
else {
$iwcmd .= " txpower auto";
}
# Allow this too.
if (exists($settings->{"sensitivity"})) {
$iwcmd .= " sens " . $settings->{"sensitivity"};
}
#
# We demand to be told if we are the master or a peon.
# This needs to be last for some reason.
#
if (!exists($settings->{"accesspoint"})) {
warn("*** WARNING: No accesspoint provided for $iface!\n");
return undef;
}
my $accesspoint = $settings->{"accesspoint"};
if (libsetup::findiface($accesspoint) eq $iface) {
$iwcmd .= " mode Master";
}
else {
if ($accesspoint =~ /^(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})$/) {
$accesspoint = "$1:$2:$3:$4:$5:$6";
$iwcmd .= " mode Managed ap $accesspoint";
}
else {
warn("*** WARNING: Bad accesspoint provided for $iface!\n");
return undef;
}
}
$uplines = sprintf($IFCONFIG, $iface, $inet, $mask) . "\n";
$uplines .= $privcmd . "\n";
$uplines .= $iwcmd;
$downlines = "$IFCONFIGBIN $iface down";
return ($uplines, $downlines);
}
#
# Need to check units on the speed. Just in case.
......@@ -154,18 +267,19 @@ sub os_ifconfig_line($$$$$$;$)
#
if (-e "/usr/sbin/ethtool") {
# this seems to work for returning an error on eepro100
$ifc = "if /usr/sbin/ethtool $iface >/dev/null 2>&1; then\n " .
$uplines = "if /usr/sbin/ethtool $iface >/dev/null 2>&1; then\n " .
" /usr/sbin/ethtool -s $iface autoneg off speed $speed duplex $duplex\n " .
"else\n " .
" /sbin/mii-tool --force=$media $iface\n " .
"fi\n ";
} else {
$ifc = "/sbin/mii-tool --force=$media $iface\n ";
$uplines = "/sbin/mii-tool --force=$media $iface\n ";
}
$ifc .= sprintf($IFCONFIG, $iface, $inet, $mask);
$uplines .= sprintf($IFCONFIG, $iface, $inet, $mask);
$downlines = "$IFCONFIGBIN $iface down";
return "$ifc";
return ($uplines, $downlines);
}
#
......
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