diff options
Diffstat (limited to 'perl-install/network/ethernet.pm')
| -rw-r--r-- | perl-install/network/ethernet.pm | 127 |
1 files changed, 65 insertions, 62 deletions
diff --git a/perl-install/network/ethernet.pm b/perl-install/network/ethernet.pm index 6f9cc8c85..8594f8708 100644 --- a/perl-install/network/ethernet.pm +++ b/perl-install/network/ethernet.pm @@ -11,26 +11,18 @@ use network::tools; use vars qw(@ISA @EXPORT); @ISA = qw(Exporter); -@EXPORT = qw(conf_network_card_backend); +@EXPORT = qw(get_eth_categories); sub write_ether_conf { - my ($in, $netcnx, $netc, $intf) = @_; - configureNetwork2($in, $::prefix, $netc, $intf); + my ($in, $modules_conf, $netcnx, $netc, $intf) = @_; + configureNetwork2($in, $modules_conf, $::prefix, $netc, $intf); $netc->{NETWORKING} = "yes"; if ($netc->{GATEWAY} || any { $_->{BOOTPROTO} =~ /dhcp/ } values %$intf) { $netcnx->{type} = 'lan'; $netcnx->{NET_DEVICE} = $netc->{NET_DEVICE} = ''; $netcnx->{NET_INTERFACE} = 'lan'; #$netc->{NET_INTERFACE}; - set_cnx_script($netc, "local network", -qq( -/etc/rc.d/init.d/network restart -), -qq( -/etc/rc.d/init.d/network stop -/sbin/ifup lo -), $netcnx->{type}); } - $::isStandalone and modules::write_conf(); + $::isStandalone and $modules_conf->write; 1; } @@ -38,44 +30,74 @@ qq( sub mapIntfToDevice { my ($interface) = @_; my $hw_addr = c::getHwIDs($interface); + return {} if $hw_addr =~ /^usb/; my ($bus, $slot, $func) = map { hex($_) } ($hw_addr =~ /([0-9a-f]+):([0-9a-f]+)\.([0-9a-f]+)/); $hw_addr && (every { defined $_ } $bus, $slot, $func) ? grep { $_->{pci_bus} == $bus && $_->{pci_device} == $slot && $_->{pci_function} == $func } detect_devices::probeall() : {}; } +sub get_eth_categories() { + 'network/main|gigabit|pcmcia|usb|wireless|firewire'; +} + # return list of [ intf_name, module, device_description ] tuples such as: # [ "eth0", "3c59x", "3Com Corporation|3c905C-TX [Fast Etherlink]" ] -sub get_eth_cards() { +# +# this function try several method in order to get interface's driver and description in order to support both: +# - hotplug managed devices (USB, firewire) +# - special interfaces (IP aliasing, VLAN) +sub get_eth_cards { + my ($modules_conf) = @_; my @all_cards = detect_devices::getNet(); my @devs = detect_devices::pcmcia_probe(); - modules::mergein_conf(); my $saved_driver; + # compute device description and return (interface, driver, description) tuples: return map { my $interface = $_; my $description; - my $a = c::getNetDriver($interface) || modules::get_alias($interface); + # 0) get interface's driver through ETHTOOL ioctl or module aliases: + my $a = c::getNetDriver($interface) || $modules_conf->get_alias($interface); + + # workaround buggy drivers that returns a bogus driver name for the GDRVINFO command of the ETHTOOL ioctl: + my %fixes = ( + "p80211_prism2_cs" => 'prism2_cs', + "p80211_prism2_pci" => 'prism2_pci', + "p80211_prism2_usb" => 'prism2_usb', + "ip1394" => "eth1394", + "hostap" => undef, #- should be either "hostap_plx", "hostap_pci" or "hostap_cs" + "DL2K" => "dl2k", + ); + $a = $fixes{$a} if $fixes{$a}; + + # 1) try to match a PCMCIA device for device description: if (my $b = find { $_->{device} eq $interface } @devs) { # PCMCIA case $a = $b->{driver}; $description = $b->{description}; } else { + # 2) try to lookup a device by hardware address for device description: + # maybe should have we try sysfs first for robustness? ($description) = (mapIntfToDevice($interface))[0]->{description}; } + # 3) try to match a device through sysfs for driver & device description: + # (eg: ipw2100 driver for intel centrino do not support ETHTOOL) if (!$description) { my $drv = readlink("/sys/class/net/$interface/driver"); - if ($drv and $drv =~ s!.*/!!) { + if ($drv && $drv =~ s!.*/!!) { $a = $drv; my %l; my %sysfs_fields = (id => "device", subid => "subsystem_device", vendor => "vendor", subvendor => "subsystem_vendor"); $l{$_} = hex(chomp_(cat_("/sys/class/net/$interface/device/" . $sysfs_fields{$_}))) foreach keys %sysfs_fields; my @cards = grep { my $dev = $_; every { $dev->{$_} eq $l{$_} } keys %l } detect_devices::probeall(); - $description = $cards[0]{description} if $#cards == 0; + $description = $cards[0]{description} if @cards == 1; } } + # 4) try to match a device by driver for device description: + # (eg: madwifi, ndiswrapper, ...) if (!$description) { my @cards = grep { $_->{driver} eq ($a || $saved_driver) } detect_devices::probeall(); - $description = $cards[0]->{description} if $#cards == 0; + $description = $cards[0]{description} if @cards == 1; } $a and $saved_driver = $a; # handle multiple cards managed by the same driver [ $interface, $saved_driver, if_($description, $description) ] @@ -84,57 +106,38 @@ sub get_eth_cards() { sub get_eth_cards_names { my (@all_cards) = @_; - - foreach my $card (@all_cards) { - modules::remove_alias($card->[1]); - modules::set_alias($card->[0], $card->[1]); - } - { map { $_->[0] => join(': ', $_->[0], $_->[2]) } @all_cards }; } +#- returns (link_type, mac_address) +sub get_eth_card_mac_address { + my ($intf) = @_; + `LC_ALL= LANG= $::prefix/sbin/ip -o link show $intf 2>/dev/null` =~ m|.*link/(\S+)\s([0-9a-z:]+)\s|; +} -#- conf_network_card_backend : configure the specified network interface -# WARNING: you have to setup the ethernet cards, by calling load_category($in, 'network/main|gigabit|usb', !$::expert, 1) -# or load_category_backend before calling this function. -#- input -#- $netc -#- $intf -#- $type : type of interface, must be given if $interface is : string : "static" or "dhcp" -#- $interface : set this interface and return it in a proper form. -#- $ipadr : facultative, ip address of the interface : string -#- $netadr : facultative, netaddress of the interface : string -#- when $interface is given, informations are written in $intf and $netc. -#- $intf output: $device is the result of -#- $intf->{$device}->{DEVICE} : which device is concerned : $device is the result of $interface =~ /(eth[0-9]+)/; my $device = $1;; -#- $intf->{$device}->{BOOTPROTO} : $type -#- $intf->{$device}->{NETMASK} : '255.255.255.0' -#- $intf->{$device}->{NETWORK} : $netadr -#- $intf->{$device}->{ONBOOT} : "yes" -#- $netc output: -#- $netc->{NET_DEVICE} : this is used to indicate that this eth card is used to connect to internet : $device -#- output: -#- $device : returned passed interface name -sub conf_network_card_backend { - my ($netc, $intf, $type, $interface, $o_ipadr, $o_netadr) = @_; - #-type =static or dhcp - - $interface =~ /eth[0-9]+/ or die("the interface is not an ethx"); - - # FIXME: this is wrong regarding some wireless interfaces or/and if user play if ifname(1): - $netc->{NET_DEVICE} = $interface; #- one consider that there is only ONE Internet connection device.. - - @{$intf->{$interface}}{qw(DEVICE BOOTPROTO NETMASK NETWORK ONBOOT)} = ($interface, $type, '255.255.255.0', $o_netadr, 'yes'); - - $intf->{$interface}{IPADDR} = $o_ipadr if $o_ipadr; - $interface; +#- write interfaces MAC address in iftab +sub update_iftab() { + foreach my $intf (detect_devices::getNet()) { + my ($link_type, $mac_address) = get_eth_card_mac_address($intf) or next; + my $descriptor = ${{ ether => 'mac', ieee1394 => 'mac_ieee1394' }}{$link_type} or next; + substInFile { + s/^$intf\s+.*\n//; + $_ .= qq($intf\t$descriptor $mac_address\n) if eof + } "$::prefix/etc/iftab"; + } } # automatic net aliases configuration -sub configure_eth_aliases() { - foreach (detect_devices::getNet()) { - my $driver = c::getNetDriver($_) or next; - modules::set_alias($_, $driver); +sub configure_eth_aliases { + my ($modules_conf) = @_; + my @pcmcia = detect_devices::pcmcia_probe(); + foreach my $card (get_eth_cards($modules_conf)) { + if (any { $_->{device} eq $card->[0] } @pcmcia) { + #- don't write aliases for pcmcia cards, or cardmgr won't be loaded + $modules_conf->remove_alias($card->[0]); + } else { + $modules_conf->set_alias($card->[0], $card->[1]); + } } } |
