Why is delay after ifconfig down needed before up if changing MAC address?
Solution 1
The delay in bringing down the interface is likely related to the driver and/or hardware for the interface. If that is correct, then there is no standard way to know when the driver or hardware have truly put the interface down.
Reading through the rest of the troubleshooting more, it sounds like there could be a competing process in play - especially the part about the interface coming back up "on its own". Perhaps there is a tool that runs and puts the interface back up after the attempt to take it down?
That would be a little tricky to detect, but not impossible. I can't think of any quick and easy way to suggest that you could detect it.
Solution 2
I don't think a delay is required. Before putting the interface down, you should be able to physically disconnect from the old MAC address. I'm on wireless at the moment, so I can't test this out right now, but look at the ifconfig --help. Something like this?:
ifconfig <interface> del <address>
On wireless, when I disconnect, I run a little script that clears everything, including the AP's MAC address:
sudo dhcpcd --release "$INTERFACE"
sudo iwconfig "$INTERFACE" essid off
sudo iwconfig "$INTERFACE" ap off
sudo ifconfig "$INTERFACE" down
Related videos on Youtube
piotrekkr
Updated on September 18, 2022Comments
-
piotrekkr over 1 year
Hi I made bash script to put down my interface, change MAC address and get it up again.
#!/bin/bash INTERFACE_STATUS=$( cat /sys/class/net/eth0/operstate ) echo "$INTERFACE_STATUS" if [ "$INTERFACE_STATUS" == "up" ] then echo "Putting down eth0" sudo ifconfig eth0 down # putting down eth0 works only when I sleep 10 seconds after using command #sleep 10 echo "$( cat /sys/class/net/eth0/operstate )" # TRIES=0 # while [ "$( cat /sys/class/net/eth0/operstate )" == "up" ] # do # sleep 1 # TRIES=$(($TRIES + 1)) # if [ "$TRIES" == "7" ] # then # echo Could not put down eth0 # exit 1 # fi # done fi sudo ifconfig eth0 hw ether "91:91:91:91:91:91" sudo ifconfig eth0 up
The problem is that it does not work. Immediately after putting down eth0
/sys/class/net/eth0/operstate
changes todown
but it seems like it isn't down yet. I takes like 10 seconds to put down interface eth0 so only way to make it work is to addsleep 10
after putting down eth0.So my question is how to check if eht0 is really down?
//EDIT
It's like command
ifconfig eth0 up
is used to early because it never gets up with new MAC address. I need to put it down, wait 10 s, change MAC and put it back again. I suspect that putting down eth0 takes few seconds and putting it up again too early does not work.//EDIT 2
I checked MAC address again and it seems that it's changed, so now I think that it could be something with DNS because when I'm using ping on google I get unknown host. But same method with
sleep 10
does work.// EDIT 3
After using script without
sleep 10
I tried using ping:piotrek@piotrek-Vostro-2520:~$ ping 212.77.100.101 connect: Network is unreachable piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101 connect: Network is unreachable piotrek@piotrek-Vostro-2520:~$ ifconfig eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55 inet addr:10.36.253.122 Bcast:10.36.253.255 Mask:255.255.255.0 inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:74297 errors:0 dropped:0 overruns:0 frame:0 TX packets:38597 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:32417366 (32.4 MB) TX bytes:5201537 (5.2 MB)0 collisions:0 txqueuelen:1000 RX bytes:32417366 (32.4 MB) TX bytes:5201537 (5.2 MB)
//EDIT 4 SUM UP
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101 connect: Network is unreachable piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101 PING 212.77.100.101 (212.77.100.101) 56(84) bytes of data. 64 bytes from 212.77.100.101: icmp_req=1 ttl=246 time=8.91 ms 64 bytes from 212.77.100.101: icmp_req=2 ttl=246 time=8.76 ms 64 bytes from 212.77.100.101: icmp_req=3 ttl=246 time=8.52 ms ^C --- 212.77.100.101 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 8.523/8.734/8.917/0.194 ms
Why
sleep 10
matters?// EDIT 5
Its getting quite weird. When I use
sleep
it works fine. When I try withoutsleep
it looks like IP is ok, interface is up, but network does not work. When I try put downeth0
withsudo ifconfig eth0 down
after few seconds my OS (ubuntu 12.10) reconects me automaticly with my old MAC address and I get new IP. With second use ofsudo ifconfig eth0 down
I'm able to fully put downeth0
.piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55 inet addr:10.36.253.241 Bcast:10.36.253.255 Mask:255.255.255.0 inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:439341 errors:0 dropped:0 overruns:0 frame:0 TX packets:224187 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:400718780 (400.7 MB) TX bytes:26246307 (26.2 MB) piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101 connect: Network is unreachable piotrek@piotrek-Vostro-2520:~$ ifconfig eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55 inet addr:10.36.253.241 Bcast:10.36.253.255 Mask:255.255.255.0 inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:439656 errors:0 dropped:0 overruns:0 frame:0 TX packets:224321 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:400827185 (400.8 MB) TX bytes:26267012 (26.2 MB) piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down piotrek@piotrek-Vostro-2520:~$ ifconfig eth0 Link encap:Ethernet HWaddr e0:db:55:97:de:cc inet addr:10.36.253.122 Bcast:10.36.253.255 Mask:255.255.255.0 inet6 addr: fe80::e2db:55ff:fe97:decc/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:440302 errors:0 dropped:0 overruns:0 frame:0 TX packets:224862 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:401129508 (401.1 MB) TX bytes:26323176 (26.3 MB) piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down piotrek@piotrek-Vostro-2520:~$ ifconfig eth0 eth0 Link encap:Ethernet HWaddr e0:db:55:97:de:cc BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:440437 errors:0 dropped:0 overruns:0 frame:0 TX packets:224881 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:401147424 (401.1 MB) TX bytes:26326068 (26.3 MB)
//EDIT 6
I've tried solution suggested by @Moreaki but the same thing happens. Script runs around one second but my network is unreachable after using it. This is the code from @Moreaki:
#!/usr/bin/env bash INTF=eth0 INTERFACE_STATUS=$(cat /sys/class/net/${INTF}/operstate) echo "$INTERFACE_STATUS" if [ "$INTERFACE_STATUS" == "up" ]; then echo "Putting down ${INTF}" # if you need to remove all IP addresses associated with ${INTF} sudo ip addr flush dev ${INTF} # set the interface status down sudo ip link set dev ${INTF} down # flush neighbour cache sudo ip neigh flush dev ${INTF} # flush routing cache entries pertaining to ${INTF} sudo ip route flush table cache dev ${INTF} echo "New state: $(cat /sys/class/net/${INTF}/operstate)" fi sudo ip link set dev ${INTF} address "08:3e:8e:2d:36:55" sudo ip link set dev ${INTF} up
After using it I get:
piotrek@piotrek-Vostro-2520:~$ ./mac_test.sh up Putting down eth0 New state: down
And after trying ping:
piotrek@piotrek-Vostro-2520:~$ ping google.com ping: unknown host google.com piotrek@piotrek-Vostro-2520:~$ ping 8.8.8.8 connect: Network is unreachable
//EDIT 7
Using routing script from @Moreaki my routing before changing mac address looks like this:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh Destination Gateway Source Iface R_Type RT_table default 10.36.253.1 10.36.253.122 eth0 main 10.36.253.0/24 0.0.0.0 10.36.253.122 eth0 main 169.254.0.0/16 0.0.0.0 10.36.253.122 eth0 main
And after changing MAC address using my script with 10s delay:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh Destination Gateway Source Iface R_Type RT_table default 10.36.253.1 10.36.253.241 eth0 main 10.36.253.0/24 0.0.0.0 10.36.253.241 eth0 main 169.254.0.0/16 0.0.0.0 10.36.253.241 eth0 main
Routing after using @Moreaki script:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh Destination Gateway Source Iface R_Type RT_table
@Moreaki also suggested to comment line
sudo ip addr flush dev ${INTF}
but I still getconnect: Network is unreachable
. My routing after using his script with commented line looks like this:piotrek@piotrek-Vostro-2520:~$ ./routing.sh Destination Gateway Source Iface R_Type RT_table 10.36.253.0/24 0.0.0.0 10.36.253.122 eth0
-
user over 10 yearsIn what way do you mean that the interface is not down when sysfs reports it as down?
ifconfig eth0 down
almost certainly makes a call to the kernel to effect the change, and sysfs reads the internal kernel data structures, so I don't see how sysfs could report the interface being down when it really is not. Maybe you are referring to something related but different? -
piotrekkr over 10 yearsIt's like command
ifconfig eth0 up
is used to early because it never gets up with new MAC address. I need to put it down, wait 10 s, change MAC and put it back again. See my edited post -
user over 10 yearsSo your question is really "why does the sequence
ifconfig eth0 down
,ifconfig eth0 hw ether ...
,ifconfig eth0 up
with no intervening delays not change the MAC address on eth0, when adding a delay betweendown
andether
does?", correct? -
Marek Zakrzewski over 10 yearsUse
grep -q "up" /sys/class/net/eth0/operstate && sudo ifdown eth0
This is a more accurate way of doing checks in bash. Also useifdown eth0
instead. This uses ifconfig to configure the interfaces. -
piotrekkr over 10 years@MichaelKjörling I check MAC again and it seems like it is changed so now I think it's more like DNS problem than interface. I get like unknown host when trying to ping google.
-
user over 10 yearsMy guess given the newly added information would be in the direction of the ARP cache. Try to ping an IP address (without name resolution on the response, so
ping -n
) rather than something which requires DNS resolution. -
piotrekkr over 10 years@MichaelKjörling ping does not work. I get network unreachable but ifconfig seems ok. See my edit
-
user over 10 yearsNow we're getting somewhere. I don't have an answer, but this looks like it's answerable. I gave the question a better title, too, which hopefully summarizes what the question is about.
-
Raphael Ahrens over 10 yearsDo you use DHCP to get your IP?
-
piotrekkr over 10 years@RaphaelAhrens Yes, IP is from DHCP.
-
Raphael Ahrens over 10 years@piotrekkr could it then be that the exchange between the DHCP server and your machine takes up to 10 seconds?
-
piotrekkr over 10 years@RaphaelAhrens It might take like 10 seconds. Maby I'm wrong but isn't it
ifconfig eth0 up
that take new IP from DHCP, notifconfig eth0 down
?Sleep 10
is afterifconfig eth0 down
. -
Raphael Ahrens over 10 years@piotrekkr You have the
DHCPRELEASE
commando so the DHCP server knows that it can reuse the IP address. You could try it without DHCP. -
Raphael Ahrens over 10 years@piotrekkr mhh but it will not be the only thing.
-
piotrekkr over 10 years@RaphaelAhrens I updated my post. After using command without
sleep
it looks like working but network is unreachable. So I tried to just put downeth0
and I was surprised because afterifconfig eth0 down
I've got reconnected with my old MAC address and with old IP. I could fully put down eth0 after usingifconfig eth0 down
second time. -
BatchyX over 10 yearsWhat hardware is this ? it could be a driver bug.
-
-
wchargin over 10 yearsIf
ifconfig
is deprecated, what should we use instead? -
Moreaki over 10 yearsThe
iproute2
framework that was introduced in kernel 2.1.x. You can find more documentation here. -
piotrekkr over 10 years@Moreaki Thanks for your suggestion but It didn't work. See my last edit. Your script works for like one second and after using it my network is unreachable.
-
Moreaki over 10 yearsWell, from what I see, unless you add an IP address when you fire you device up again (after flushing all IP addresses), things won't work. So, either add an IP address into the script or do not execute the line
sudo ip addr flush dev ${INTF}
in my snippet, as I hinted in my comment. -
Moreaki over 10 yearsJudging from your new output (though I believe you have mixed the explanation with the actual output in the last two comment paragraphs), you are missing your default route and it seems that you are also running a dhclient. So, disable this client and add the default route as follows:
sudo ip route add default via 10.36.253.1 dev ${INTF}
. You can add it at the end of the script. If you decide to flush the IP address(es), you also have to add your IP address again:sudo ip addr add 10.36.253.241/24 brd + dev eth0 label eth0
before the default route setup. -
Moreaki over 10 yearsSo far I didn't have enough information to know if you needed DHCP or not, I only judged based on the output you provided, and there you have the routing entry
169.254.0.0/16
. This means that DHCP didn't get an IP address. I don't recall the exact inner workings of the DHCP client when interface state changes occur. Now, besides this, have you tried my suggestion to add the default route as suggested in my last comment? From what I can see, there's really nothing special in you setup and it should just work. -
piotrekkr over 10 yearsI'll try adding default route on monday when I'm back to work. So after I use your script with or without
sudo ip addr flush dev ${INTF}
, it seams that I don't get new IP? How can I force DHCP to give me new IP? -
ash over 10 yearsDisagree on deprecation of ifconfig. Sometimes, the old tools are fine just the way they are.