Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 75570
Summary: | Bounding a network interface config to a HWADDR does not work | ||||||||
---|---|---|---|---|---|---|---|---|---|
Product: | [Retired] Red Hat Linux | Reporter: | diego.santacruz | ||||||
Component: | initscripts | Assignee: | Bill Nottingham <notting> | ||||||
Status: | CLOSED CURRENTRELEASE | QA Contact: | Brock Organ <borgan> | ||||||
Severity: | medium | Docs Contact: | |||||||
Priority: | medium | ||||||||
Version: | 8.0 | CC: | craig.lawson, jeremyp, mike, olc, rvokal | ||||||
Target Milestone: | --- | ||||||||
Target Release: | --- | ||||||||
Hardware: | i686 | ||||||||
OS: | Linux | ||||||||
Whiteboard: | |||||||||
Fixed In Version: | Doc Type: | Bug Fix | |||||||
Doc Text: | Story Points: | --- | |||||||
Clone Of: | Environment: | ||||||||
Last Closed: | 2003-10-30 05:25:10 UTC | Type: | --- | ||||||
Regression: | --- | Mount Type: | --- | ||||||
Documentation: | --- | CRM: | |||||||
Verified Versions: | Category: | --- | |||||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||
Cloudforms Team: | --- | Target Upstream Version: | |||||||
Embargoed: | |||||||||
Attachments: |
|
Description
diego.santacruz
2002-10-09 22:16:37 UTC
nameif bug reported in bug #75572 There is a bug in ifdown (I looking at initscripts-6.95-1). When the interface macaddr does not match the one in the config, ifdown looks for another config file *with the same nonmatching macaddr*. The following patch will fix this little problem, but not the larger one. --- ifdown.orig 2002-10-18 18:35:46.000000000 -0700 +++ ifdown 2002-10-18 18:37:57.000000000 -0700 @@ -52,7 +52,7 @@ FOUNDMACADDR=`LC_ALL= LANG= ip -o link show ${REALDEVICE} | \ sed 's/.*link\/ether \([[:alnum:]:]*\).*/\1/'` if [ "${FOUNDMACADDR}" != "${HWADDR}" ]; then - NEWCONFIG=`fgrep -l "HWADDR=${HWADDR}" /etc/sysconfig/network-scripts/ifcfg-*` + NEWCONFIG=`fgrep -l "HWADDR=${FOUNDMACADDR}" /etc/sysconfig/network-scripts/ifcfg-*` if [ -n "${NEWCONFIG}" -a "${NEWCONFIG}" != "${CONFIG}" ]; then exec /sbin/ifdown ${NEWCONFIG} else Also we should probably decide on a standard for the case of HWADDR. /sbin/ip reports them lower case, but neat writes them uppercase in the config file. Optionally, we could just make the test case insensitive with something like echo "$HWADDR" |fgrep -qix "$FOUNDMACADDR" I ran into the same problem with the case of the HWADDR. Fixing this solves the problem for me. I used this patch to make sure both are uppercase (allowing for the fact that the config file might be lowercase too if hand-edited). --- ifdown 2002-10-19 11:32:47.000000000 -0400 +++ ifdown.good 2002-10-19 11:31:43.000000000 -0400 @@ -51,6 +51,9 @@ if [ -n "${HWADDR}" ]; then FOUNDMACADDR=`LC_ALL= LANG= ip -o link show ${REALDEVICE} | \ sed 's/.*link\/ether \([[:alnum:]:]*\).*/\1/'` + # uppercase the mac address variables + FOUNDMACADDR=`echo ${FOUNDMACADDR} | tr a-f A-F` + HWADDR=`echo ${HWADDR} | tr a-f A-F` if [ "${FOUNDMACADDR}" != "${HWADDR}" ]; then NEWCONFIG=`fgrep -l "HWADDR=${HWADDR}" /etc/sysconfig/network-scripts/ifcfg-*` if [ -n "${NEWCONFIG}" -a "${NEWCONFIG}" != "${CONFIG}" ]; then *** Bug 76599 has been marked as a duplicate of this bug. *** *** Bug 76598 has been marked as a duplicate of this bug. *** Created attachment 91383 [details]
bash replacement for nameif(8)
This bug has bitten me on both RH8 and RH9 systems, and is particularly egregious when using multiple interfaces driven by the same card -- since all interfaces get named as soon as the module loads, nameif(8) refuses to rename (e.g.) eth2 to eth0 because eth0 already exists. I swore at this for some time and finally ended up writing a more-or-less drop-in replacement for nameif in bash, using "ip link" commands. This simplifies things greatly for me, and so far it works like a charm. Attached; you can also find a copy at http://www.cs.umass.edu/~olc/pub/nameif. Comment on attachment 91383 [details] bash replacement for nameif(8) #!/bin/bash # Copyright (c) 2003 Ole Craig <olc.edu>, all rights # reserved. This software may be freely redistributed under the terms # of the GNU general public license. See (e.g.) # http://www.gnu.org/licenses/gpl.txt for details. Although it is not # required by the license terms, if you improve this script in any way # the author would deeply appreciate seeing (and perhaps learning # from) your changes. # we use this script because regular nameif doesn't handle the case # where we want to rename preexisting devices (e.g. swap eth0 <--> # eth1) and sometimes segfaults anyway. # quick'n'dirty method for dealing with errout (overrideable with -s) logger="echo `basename $0[$$]`: " function usage() { echo "usage: `basename $0` [-c configurationfile] [-s] {ifname macaddress}" exit -1 } function loggit() { $logger "$*" } function die () { loggit $* exit -1 } function namer() { # this is where we do the work on a given IF # expect 2 inputs: current name targetname err=`ip link set $1 name $2` status=$? if [ "$err" != "" ]; then $logger $err fi return $status } function isup() { # check to see if interface is active ip link show $1 2>&1 | cut -f3 -d" " | grep -qw UP return $? } # main body if [ ${#*} == 0 ]; then # we get our parameters from /etc/mactab unless otherwise specified CONFFILE=/etc/mactab else while [ ${#*} -gt 0 ]; do case $1 in -s) logger="logger -i -t `basename $0`" shift ;; -c) if [ "$2" == "" -o ! -r $2 ]; then usage else CONFFILE=$2 shift shift fi ;; *) # we assume anything else is an interface name if [ "$2" == "" -o "$3" != "" ]; then usage else DES_IFNAME=$1 # attempt to sanitize input a bit DES_MAC=`echo $2 | tr 'a-f-' 'A-F:'` shift shift fi esac done i=0 BLOCKED=0 fi if [ "$DES_IFNAME" = "" ]; then # if we're processing a table (/etc/mactab by default) then we iterate # through... itab=0 for q in `cat $CONFFILE`; do MACTABLE[$itab]=$q let itab++ done # ...and recurse for (( q=0 ; $q < $itab ; q++)); do $0 ${MACTABLE[((q++))]} ${MACTABLE[$q]} # note nasty increment of counter within loop. Ugh. done else # we were given an argument, use it # Build table of current IFs and their associated MAC addresses. While # we're at it, grab current values for IF name and IF/MAC of blocking # name, if any. If we only have one MAC address as input, then we # scan the table of available IFs for a match. If that MAC is # currently in use by another IF name, we swap. Otherwise, we just # name it. (Or leave it alone, as may be the case.) # DES_IFNAME is the desired name for the mac address supplied on commandline. i=0 GETMAC=0 for q in `ifconfig -a | grep -E ^eth | awk '{ print $1" "$5 }'`; do MACDESK[$i]=$q if [ "$GETMAC" != "0" ]; then CUR_MAC=$q GETMAC=0 fi if [ "$q" == "$DES_MAC" ]; then CUR_IFNAME=${MACDESK[$i-1]} fi if [ "$q" == "$DES_IFNAME" ]; then BLOCKED=1 GETMAC=1 fi let i++ done # CUR_IFNAME is the current name for the mac address supplied on commandline. # if $CUR_IFNAME is empty at this point, then we don't have an # interface with this MAC address if [ "$CUR_IFNAME" == "" ]; then die "no interface found with requested MAC address \"$DES_MAC\"" fi # swap "blocked" names isup $DES_IFNAME && die "$DES_IFNAME ($CUR_MAC) already active" isup $CUR_IFNAME && die "$CUR_IFNAME ($DES_MAC) already active" if [ "$CUR_IFNAME" == "$DES_IFNAME" ]; then exit 0 # everything's jake, current and desired IF names are the same fi if [ $BLOCKED == 1 ]; then namer $DES_IFNAME nameif_tmp$DES_IFNAME namer $CUR_IFNAME $DES_IFNAME namer nameif_tmp$DES_IFNAME $CUR_IFNAME else namer $CUR_IFNAME $DES_IFNAME fi fi Comment on attachment 91383 [details] bash replacement for nameif(8) #!/bin/bash # Copyright (c) 2003 Ole Craig <olc.edu>, all rights # reserved. This software may be freely redistributed under the terms # of the GNU general public license. See (e.g.) # http://www.gnu.org/licenses/gpl.txt for details. Although it is not # required by the license terms, if you improve this script in any way # the author would deeply appreciate seeing (and perhaps learning # from) your changes. # we use this script because regular nameif doesn't handle the case # where we want to rename preexisting devices (e.g. swap eth0 <--> # eth1) and sometimes segfaults anyway. # quick'n'dirty method for dealing with errout (overrideable with -s) logger="echo `basename $0[$$]`: " function usage() { echo "usage: `basename $0` [-c configurationfile] [-s] {ifname macaddress}" exit -1 } function loggit() { $logger "$*" } function die () { loggit $* exit -1 } function namer() { # this is where we do the work on a given IF # expect 2 inputs: current name targetname err=`ip link set $1 name $2` status=$? if [ "$err" != "" ]; then $logger $err fi return $status } function isup() { # check to see if interface is active ip link show $1 2>&1 | cut -f3 -d" " | grep -qw UP return $? } # main body if [ ${#*} == 0 ]; then # we get our parameters from /etc/mactab unless otherwise specified CONFFILE=/etc/mactab else while [ ${#*} -gt 0 ]; do case $1 in -s) logger="logger -i -t `basename $0`" shift ;; -c) if [ "$2" == "" -o ! -r $2 ]; then usage else CONFFILE=$2 shift shift fi ;; *) # we assume anything else is an interface name if [ "$2" == "" -o "$3" != "" ]; then usage else DES_IFNAME=$1 # attempt to sanitize input a bit DES_MAC=`echo $2 | tr 'a-f-' 'A-F:'` shift shift fi esac done i=0 BLOCKED=0 fi if [ "$DES_IFNAME" = "" ]; then # if we're processing a table (/etc/mactab by default) then we iterate # through... itab=0 for q in `cat $CONFFILE`; do MACTABLE[$itab]=$q let itab++ done # ...and recurse for (( q=0 ; $q < $itab ; q++)); do $0 ${MACTABLE[((q++))]} ${MACTABLE[$q]} # note nasty increment of counter within loop. Ugh. done else # we were given an argument, use it # Build table of current IFs and their associated MAC addresses. While # we're at it, grab current values for IF name and IF/MAC of blocking # name, if any. If we only have one MAC address as input, then we # scan the table of available IFs for a match. If that MAC is # currently in use by another IF name, we swap. Otherwise, we just # name it. (Or leave it alone, as may be the case.) # DES_IFNAME is the desired name for the mac address supplied on commandline. i=0 GETMAC=0 for q in `ifconfig -a | grep -E ^eth | awk '{ print $1" "$5 }'`; do MACDESK[$i]=$q if [ "$GETMAC" != "0" ]; then CUR_MAC=$q GETMAC=0 fi if [ "$q" == "$DES_MAC" ]; then CUR_IFNAME=${MACDESK[$i-1]} fi if [ "$q" == "$DES_IFNAME" ]; then BLOCKED=1 GETMAC=1 fi let i++ done # CUR_IFNAME is the current name for the mac address supplied on commandline. # if $CUR_IFNAME is empty at this point, then we don't have an # interface with this MAC address if [ "$CUR_IFNAME" == "" ]; then die "no interface found with requested MAC address \"$DES_MAC\"" fi # swap "blocked" names isup $DES_IFNAME && die "$DES_IFNAME ($CUR_MAC) already active" isup $CUR_IFNAME && die "$CUR_IFNAME ($DES_MAC) already active" if [ "$CUR_IFNAME" == "$DES_IFNAME" ]; then exit 0 # everything's jake, current and desired IF names are the same fi if [ $BLOCKED == 1 ]; then namer $DES_IFNAME nameif_tmp$DES_IFNAME namer $CUR_IFNAME $DES_IFNAME namer nameif_tmp$DES_IFNAME $CUR_IFNAME else namer $CUR_IFNAME $DES_IFNAME fi fi Aaaah! Sorry about that. The original attachment was bogus -- I grabbed the old nameif instead of my replacement. Then, misunderstanding some bugzilla functionality that I don't often use, I tried to rectify my mistake by replacing the attachment with the correct file... Sigh. Compound that with a cached POST operation, and Anyway, there it is. Sorry for the extra pagefiller. Created attachment 91386 [details]
drop-in replacement for nameif(8)
The real bashful nameif...
I was burned by this bug, too. The source of my problem was the configuration files /etc/sysconfig/network-scripts/ifcfg-eth? and /etc/sysconfig/networking. I upgraded my system, replacing a NIC with an ethernet driver built into the motherboard. This made the MAC addresses in the configuration files incorrect. Also, redhat-config-network put DEVICE=eth1 in my eth0 file and vice versa. After upgrading, the MAC confusion failed the weak FOUNDMACADDR test, and the swapped device assignments assured that the script would invoke itself forever through exec. Any of the suggestions in this bug report would have caught my problems. Something similar to this (but different) is in both RHEL3 and Fedora Core. |