[SOLVED] Link is up, link is down @ restart

Hi all,

the lan 4 switch port of my GL.inet GL-MT6000 (FLINT2) is wired connected to the lan4 switch port of my Linksys WRT1900ACS-V2 (LINKSYS); everything works fine, but I noticed that when I restart the LINSYS, FLINT2's system logs shows several lan4 link is down and lan4 link is up until lan4 is definitively up.

What follows is what happened when I restarted LINKSYS @ 13:27:51 hrs:

FLINT2 system log
13:27:51 daemon.notice netifd: Network device 'lan4' link is down
13:27:51 daemon.notice netifd: Interface 'LINKSYS' has link connectivity loss
13:27:51 daemon.notice netifd: Interface 'LINKSYS' is now down
13:27:51 kern.info kernel: [325075.505117] br-lan: port 4(lan4) entered disabled state
13:27:51 kern.info kernel: [325075.505233] mt7530-mdio mdio-bus:1f lan4: Link is Down
13:28:02 kern.info kernel: [325085.916808] mt7530-mdio mdio-bus:1f lan4: Link is Up - 1Gbps/Full - flow control off
13:28:02 kern.info kernel: [325085.916832] br-lan: port 4(lan4) entered blocking state
13:28:02 kern.info kernel: [325085.929937] br-lan: port 4(lan4) entered forwarding state
13:28:02 daemon.notice netifd: Network device 'lan4' link is up
13:28:02 daemon.notice netifd: Interface 'LINKSYS' has link connectivity
13:28:02 daemon.notice netifd: Interface 'LINKSYS' is setting up now
13:28:02 daemon.notice netifd: Interface 'LINKSYS' is now up
13:28:07 daemon.notice netifd: Network device 'lan4' link is down
13:28:07 daemon.notice netifd: Interface 'LINKSYS' has link connectivity loss
13:28:07 daemon.notice netifd: Interface 'LINKSYS' is now down
13:28:07 kern.info kernel: [325091.549250] br-lan: port 4(lan4) entered disabled state
13:28:07 kern.info kernel: [325091.549364] mt7530-mdio mdio-bus:1f lan4: Link is Down
13:28:11 kern.info kernel: [325094.728596] mt7530-mdio mdio-bus:1f lan4: Link is Up - 1Gbps/Full - flow control off
13:28:11 kern.info kernel: [325094.728618] br-lan: port 4(lan4) entered blocking state
13:28:11 daemon.notice netifd: Network device 'lan4' link is up
13:28:11 daemon.notice netifd: Interface 'LINKSYS' has link connectivity
13:28:11 daemon.notice netifd: Interface 'LINKSYS' is setting up now
13:28:11 daemon.notice netifd: Interface 'LINKSYS' is now up
13:28:11 kern.info kernel: [325094.741729] br-lan: port 4(lan4) entered forwarding state
13:28:28 daemon.notice netifd: Network device 'lan4' link is down
13:28:28 daemon.notice netifd: Interface 'LINKSYS' has link connectivity loss
13:28:28 daemon.notice netifd: Interface 'LINKSYS' is now down
13:28:28 kern.info kernel: [325112.359519] br-lan: port 4(lan4) entered disabled state
13:28:28 kern.info kernel: [325112.359638] mt7530-mdio mdio-bus:1f lan4: Link is Down
13:28:32 kern.info kernel: [325115.579723] mt7530-mdio mdio-bus:1f lan4: Link is Up - 1Gbps/Full - flow control rx/tx
13:28:32 kern.info kernel: [325115.579746] br-lan: port 4(lan4) entered blocking state
13:28:32 daemon.notice netifd: Network device 'lan4' link is up
13:28:32 daemon.notice netifd: Interface 'LINKSYS' has link connectivity
13:28:32 daemon.notice netifd: Interface 'LINKSYS' is setting up now
13:28:32 kern.info kernel: [325115.593026] br-lan: port 4(lan4) entered forwarding state
13:28:32 daemon.notice netifd: Interface 'LINKSYS' is now up
LINKSYS system log
13:28:07 mv88e6085 f1072004.mdio-mii:00 lan4 (uninitialized): PHY [mv88e6xxx-0:00] driver [Marvell 88E1540] (irq=60)
13:28:28 mv88e6085 f1072004.mdio-mii:00 lan4: configuring for phy/gmii link mode
13:28:28 br-lan: port 4(lan4) entered blocking state
13:28:28 br-lan: port 4(lan4) entered disabled state
13:28:28 mv88e6085 f1072004.mdio-mii:00 lan4: entered allmulticast mode
13:28:28 mv88e6085 f1072004.mdio-mii:00 lan4: entered promiscuous mode
13:28:32 mv88e6085 f1072004.mdio-mii:00 lan4: Link is Up - 1Gbps/Full - flow control rx/tx
13:28:32 br-lan: port 4(lan4) entered blocking state
13:28:32 br-lan: port 4(lan4) entered forwarding state

As you can see, when LINKSYS says:
13:28:32 mv88e6085 f1072004.mdio-mii:00 lan4: Link is Up - 1Gbps/Full - flow control rx/tx,

FLINT2 logs says:
13:28:32 kern.info kernel: [325115.579723] mt7530-mdio mdio-bus:1f lan4: Link is Up - 1Gbps/Full - flow control rx/tx and 13:28:32 daemon.notice netifd: Interface 'LINKSYS' is now up.

After that, no more link down/up; it's as if lan4 @ FLINT2 flickers down and up while LINKSYS is restarting and it stops doing that as soon as LINKSYS says "I'm up".

Moreover, I get exactly he same behavior when FLINT2's lan2 is wired connected to another device and I restart this device, but it does not happen when I switch on my PS/4 wired connected to FLINT2's lan3 port.

The question is: how can I stop the lan4 (and lan2) down and up @ FLINT2 side when a wired connected device is restarted?

Thanks a lot in advance.

Forgive me if I am misunderstanding your question, but I don't understand the actual problem with what you've described. When a network interface is being enabled/disabled/restarted/etc. it is going to go through state transitions. Those up/down state transitions will be reflected on the other side of the cable.

That's just the nature of a NIC.

As to why your PS/4 doesn't show the same behavior--I would say it is likely due to your PS/4 going into a low-power (sleep) mode when you "power it off". The PS/4 NIC likely stays connected even in that case for the purposes of background updates, remote connections, etc. So you would not see the same up/down behavior of a NIC being restarted and brought online. If you fully unplug your PS/4, though, I bet you'd see it reflected in the FLINT2 log. :wink:

Hopefully I didn't misunderstand your question. If I did, feel free to correct any of my misunderstandings. :slight_smile:

1 Like

Well, thanks on your kind reply it won't probably be a problem, i.e. a fault somewhere... anyway I'll double check the PS/4 :wink:

But, assuming I can't avoid this behavior, it's annoying because I have an hotplug script on FLINT2 which sends me an email when LINKSYS goes down ("$ACTION" = "ifdown") and returns up ("$ACTION" = "ifup"), which means "wrong" warnings... :thinking:

Yeah, I see now why this is more troublesome for you. Is it safe to assume your LINKSYS device has a static IP address that would respond to ICMP echo?

If so, something like this in your iface hotplug script might help mitigate the amount of ifup notifications (change linksys_ip as needed to match your environment):

linksys_ip="192.168.1.2"

if [ "$ACTION" = "ifup" ] && [ "$INTERFACE" = "LINKSYS" ] && ping -c2 $linksys_ip >/dev/null 2>&1; then
    logger -t LINKSYS "Linksys interface is up and device is online!"
    # Send an email notification here...
fi

This wouldn't help suppress any repeated ifdown events, though. I'll try to ponder this some more and think if there is a more elegant solution.


If you were open to consider options other than hotplug, you could craft a little shell script that you could just run in the background on startup that sits in a while-loop to ping your Linksys box.

E.g.:

#!/bin/sh

linksys_ip="192.168.1.2" # IP address of the Linksys device
linksys_curr_state="down" # Initial state
linksys_prev_state="down" # Initial state

while true; do
    if ping -c2 $linksys_ip >/dev/null 2>&1; then
        linksys_curr_state="up"
    else
        linksys_curr_state="down"
    fi

    if [ $linksys_curr_state = "down" ] && [ $linksys_prev_state = "up" ]; then
        linksys_prev_state="down"
        logger -t LINKSYS "Linksys device is down!"
        # Send an email notification here...
    fi
    
    if [ $linksys_curr_state = "up" ] && [ $linksys_prev_state = "down" ]; then
        linksys_prev_state="up"
        logger -t LINKSYS "Linksys device is online!"
        # Send an email notification here...
    fi

    sleep 5 # Wait for 5 seconds before checking again
done

Nice suggestion thanks, I'll study it. In fact, LINKSYS has static IP...

Nevertheless, It would be great keeping the hotplug idea... in this case the question (and hopefully the solution) is: if "$ACTION" = "ifup" and /sys/class/net/LINKSYS/carrier = 1, is LINKSYS definitively up, i.e. no more up/down are expected because of startup negotiation process?

1 Like

That's a fantastic question and one that I frankly have not explored before. It does look like /sys/class/net/<IFACE>/carrier could be a solid indicator for not just "up" but an indication of "functional".

You might also want to watch the value of /sys/class/net/<IFACE>/operstate during a test unplug/re-plug of your Linksys box. It might also be a valid indicator that you could leverage in your hotplug script.

1 Like

Wrote a script that echoes what happens, wired a D-LINK device to FLINT's lan2 and performed some test: "$ACTION" = "ifup" and /sys/class/net/D-LINK/carrier = 1does not mean "I'm definitively up"; the same conclusion remains valid if I also consider /sys/class/net/D-LINK/operstate = 1:

FLINT2 system log
Sat May 24 18:20:15 2025 daemon.notice netifd: Network device 'lan2' link is down
Sat May 24 18:20:15 2025 daemon.notice netifd: Interface 'D-LINK' has link connectivity loss
Sat May 24 18:20:15 2025 daemon.notice netifd: Interface 'D-LINK' is now down
Sat May 24 18:20:15 2025 kern.info kernel: [1120329.014220] br-lan: port 2(lan2) entered disabled state
Sat May 24 18:20:15 2025 kern.info kernel: [1120329.014336] mt7530-mdio mdio-bus:1f lan2: Link is Down
Sat May 24 18:20:20 2025 kern.info kernel: [1120333.930353] mt7530-mdio mdio-bus:1f lan2: Link is Up - 1Gbps/Full - flow control rx/tx
Sat May 24 18:20:20 2025 kern.info kernel: [1120333.930376] br-lan: port 2(lan2) entered blocking state
Sat May 24 18:20:20 2025 kern.info kernel: [1120333.943829] br-lan: port 2(lan2) entered forwarding state
Sat May 24 18:20:20 2025 daemon.notice netifd: Network device 'lan2' link is up
Sat May 24 18:20:20 2025 daemon.notice netifd: Interface 'D-LINK' has link connectivity
Sat May 24 18:20:20 2025 daemon.notice netifd: Interface 'D-LINK' is setting up now
Sat May 24 18:20:20 2025 daemon.notice netifd: Interface 'D-LINK' is now up
Sat May 24 18:20:26 2025 daemon.notice netifd: Network device 'lan2' link is down
Sat May 24 18:20:26 2025 daemon.notice netifd: Interface 'D-LINK' has link connectivity loss
Sat May 24 18:20:26 2025 daemon.notice netifd: Interface 'D-LINK' is now down
Sat May 24 18:20:26 2025 kern.info kernel: [1120340.372120] br-lan: port 2(lan2) entered disabled state
Sat May 24 18:20:26 2025 kern.info kernel: [1120340.372235] mt7530-mdio mdio-bus:1f lan2: Link is Down
Sat May 24 18:20:29 2025 kern.info kernel: [1120342.773290] mt7530-mdio mdio-bus:1f lan2: Link is Up - 1Gbps/Full - flow control rx/tx
Sat May 24 18:20:29 2025 kern.info kernel: [1120342.773315] br-lan: port 2(lan2) entered blocking state
Sat May 24 18:20:29 2025 kern.info kernel: [1120342.786768] br-lan: port 2(lan2) entered forwarding state
Sat May 24 18:20:29 2025 daemon.notice netifd: Network device 'lan2' link is up
Sat May 24 18:20:29 2025 daemon.notice netifd: Interface 'D-LINK' has link connectivity
Sat May 24 18:20:29 2025 daemon.notice netifd: Interface 'D-LINK' is setting up now
Sat May 24 18:20:29 2025 daemon.notice netifd: Interface 'D-LINK' is now up
FLINT2 echoed script
*** ifdown on 2025-05-24 @ 18:20:15  ***
*** Carrier is 0 on 2025-05-24 @ 18:20:15  ***
D-LINK is down on 2025-05-24 @ 18:20:15 
*** ifup on 2025-05-24 @ 18:20:20  ***
*** Carrier is 1 on 2025-05-24 @ 18:20:20  ***
*** Operstate is up on 2025-05-24 @ 18:20:20  ***
D-LINK switched on 2025-05-24 @ 18:20:20, lan2 speed is 1000 Mbps.
*** ifdown on 2025-05-24 @ 18:20:26  ***
*** Carrier is 0 on 2025-05-24 @ 18:20:26  ***
D-LINK is down on 2025-05-24 @ 18:20:26 
*** ifup on 2025-05-24 @ 18:20:29  ***
*** Carrier is 1 on 2025-05-24 @ 18:20:29  ***
*** Operstate is up on 2025-05-24 @ 18:20:29  ***
D-LINK switched on 2025-05-24 @ 18:20:29, lan2 speed is 1000 Mbps.

Now I need to think about it for a while... :thinking:

Why not call external scripts that will wait (let's say 10 seconds) before sending an ifup/down notification email?

This way you could terminate the process if the interface status changes in the meantime.

if [ "$ACTION" = "ifup" -o "$ACTION" = "ifdown" ] && [ "$INTERFACE" = "LINKSYS" ]; then

case $ACTION in

  ifup)
    /usr/bin/killall -q ash /root/ifdownmail.sh
    /root/ifupmail.sh &
    ;;

  ifdown)
    /usr/bin/killall -q ash /root/ifupmail.sh
    /root/ifdownmail.sh &
    ;;

  *)
    exit 0
    ;;
esac
fi
1 Like

On Linux you have lowerup which indicates the Carrier, and UP is a state where the system or the user turn on/up the interface.

Yeah, many thanks, this is a good hint for a Plan B; Plan A still remains hotplug and maybe I found a possibile how-to... work in progress...

1 Like

Ok, hopefully I got it, even if I still have to do some tests before confirming and celebrating.

As far as I noticed, it seems that that the device (e.g. D-LINK) is definitively up as soon as the link went down and up exactly twice.

So I wrote the following hotplug script:

hotplug script
#!/bin/sh

SCRIPTNAME="99-check-devices-speed"

# Function to send email
send_email() {
    EMAIL_SUBJECT="$1"
    echo -e "Subject: $EMAIL_SUBJECT\n\n Message from $SCRIPTNAME" | msmtp myself@myemail.com
}

case $INTERFACE in     

        D-LINK )
             DEVICE="lan2"
             COUNTER_UP_FILE="/pr_home/D-LINK_UP.txt"
             COUNTER_DOWN_FILE="/pr_home/D-LINK_DOWN.txt"
             INTERFACEON="/pr_home/D-LINK-ON"
             LOGFILE="/pr_home/D-LINKSpeed.txt";;
        
        LINKSYS )
             DEVICE="lan4"
             COUNTER_UP_FILE="/pr_home/LINKSYS_UP.txt"
             COUNTER_DOWN_FILE="/pr_home/LINKSYS_DOWN.txt"
             INTERFACEON="/pr_home/LINKSYS-ON"
             LOGFILE="/pr_home/LINKSYSSpeed.txt";;
        
        * )
             # Other interfaces
             exit 0;;
esac

if [ "$ACTION" = "ifup" ]; then

        touch $INTERFACEON     

        if [ ! -f "$COUNTER_UP_FILE" ]; then
            echo 1 > "$COUNTER_UP_FILE"
            exit 0
        fi

        COUNT_UP=$(cat "$COUNTER_UP_FILE")
        COUNT_DOWN=$(cat "$COUNTER_DOWN_FILE")
        
        COUNT_UP=$(($COUNT_UP + 1))
        echo "$COUNT_UP" > $COUNTER_UP_FILE

        if [ "$COUNT_UP" -eq 2 ] && [ "$COUNT_DOWN" -eq 2 ]; then
            
            # It's definitively UP
           
            # Set the speed threshold in Mbps (e.g., 1000 for 1Gbps)
            SPEED_THRESHOLD=1000

            SPEED=$(cat /sys/class/net/$DEVICE/speed)

            # If the speed is below the threshold, write a log and send an email
            if [ "$SPEED" -lt $SPEED_THRESHOLD ]; then
                logger -t hotplug "*** $SCRIPTNAME, Interface/Device $INTERFACE/$DEVICE speed is below threshold of $SPEED_THRESHOLD Mbps. ***"
                echo -e "*** $DEVICE speed is $SPEED and below threshold of $SPEED_THRESHOLD on" $(date +"%F @ %H:%M:%S") " ***\n" >> $LOGFILE
                send_email "*** Interface/Device $INTERFACE/$DEVICE current speed is $PEED Mbps and it's below the threshold of $SPEED_THRESHOLD Mbps; maybe check if $INTERFACE is fully plugged into its socket.***"

            # Speed's not below the threshold            
            else
                logger -t hotplug "$SCRIPTNAME, Interface/Device $INTERFACE/$DEVICE switched on and running @ $SPEED Mbps." 
                echo -e "$INTERFACE switched on" $(date +"%F @ %H:%M:%S")", $DEVICE speed is $SPEED Mbps.\n" >> $LOGFILE  

                if [ "$INTERFACE" != "PS4" ]; then
                    send_email "$INTERFACE is up and running @ $SPEED Mbps."
                fi
            fi

            rm $COUNTER_UP_FILE
            rm $COUNTER_DOWN_FILE
        fi

elif [ "$ACTION" = "ifdown" ]; then
 
        if [ ! -f "$COUNTER_DOWN_FILE" ]; then

            echo 1 > "$COUNTER_DOWN_FILE"
            
            logger -t hotplug "$SCRIPTNAME, Interface/Device $INTERFACE/$DEVICE is down."
            echo -e "$INTERFACE is down on" $(date +"%F @ %H:%M:%S")" \n" >> $LOGFILE
            send_email "$INTERFACE is down."  

            # It was UP and goes DOWN
            if [ -f $INTERFACEON ]; then
                rm $INTERFACEON
                COUNT_DOWN=$(cat "$COUNTER_DOWN_FILE")
                COUNT_DOWN=$(($COUNT_DOWN + 1))
            fi
        
        else
            COUNT_DOWN=$(cat "$COUNTER_DOWN_FILE")
            COUNT_DOWN=$(($COUNT_DOWN + 1))
            echo "$COUNT_DOWN" > $COUNTER_DOWN_FILE
        fi
         
fi

The script sends the email "it is down" only when the link goes down for the first time, and sends the email "it is up" only when the link becomes up for the second time.

It also logs the event (logger and file) and check the speed to send an email if the link is up but it's speed'is below a threshold (1Gbps in my case).

Last but not least, as the code I wrote is rather messy (not a developer here), any suggestions to improve it are welcome.

Found that LINKSYS goes down and up three times before being definitively up.

So I modified the hotplug script as follows:

Modified script
#!/bin/sh

SCRIPTNAME="99-check-devices-speed"

# Function to send email
send_email() {
    EMAIL_SUBJECT="$1"
    echo -e "Subject: $EMAIL_SUBJECT\n\n Message from $SCRIPTNAME" | msmtp myself@myemail.com
}

case $INTERFACE in     

        D-LINK )
             DEVICE="lan2"
             MAX_UP=2
             MAX_DOWN=2
             COUNTER_UP_FILE="/pr_home/D-LINK_UP.txt"
             COUNTER_DOWN_FILE="/pr_home/D-LINK_DOWN.txt"
             INTERFACEON="/pr_home/D-LINK-ON"
             LOGFILE="/pr_home/D-LINKSpeed.txt";;
        
        LINKSYS )
             DEVICE="lan4"
             MAX_UP=3
             MAX_DOWN=3
             COUNTER_UP_FILE="/pr_home/LINKSYS_UP.txt"
             COUNTER_DOWN_FILE="/pr_home/LINKSYS_DOWN.txt"
             INTERFACEON="/pr_home/LINKSYS-ON"
             LOGFILE="/pr_home/LINKSYSSpeed.txt";;
        
        * )
             # Other interfaces
             exit 0;;
esac

if [ "$ACTION" = "ifup" ]; then

        touch $INTERFACEON     

        if [ ! -f "$COUNTER_UP_FILE" ]; then
            echo 1 > "$COUNTER_UP_FILE"
            exit 0
        fi

        COUNT_UP=$(cat "$COUNTER_UP_FILE")
        COUNT_DOWN=$(cat "$COUNTER_DOWN_FILE")
        
        COUNT_UP=$(($COUNT_UP + 1))
        echo "$COUNT_UP" > $COUNTER_UP_FILE

       if [ "$COUNT_UP" -eq $MAX_UP ] && [ "$COUNT_DOWN" -eq $MAX_DOWN ]; then
            
            # It's definitively UP
           
            # Set the speed threshold in Mbps (e.g., 1000 for 1Gbps)
            SPEED_THRESHOLD=1000

            SPEED=$(cat /sys/class/net/$DEVICE/speed)

            # If the speed is below the threshold, write a log and send an email
            if [ "$SPEED" -lt $SPEED_THRESHOLD ]; then
                logger -t hotplug "*** $SCRIPTNAME, Interface/Device $INTERFACE/$DEVICE speed is below threshold of $SPEED_THRESHOLD Mbps. ***"
                echo -e "*** $DEVICE speed is $SPEED and below threshold of $SPEED_THRESHOLD on" $(date +"%F @ %H:%M:%S") " ***\n" >> $LOGFILE
                send_email "*** Interface/Device $INTERFACE/$DEVICE current speed is $PEED Mbps and it's below the threshold of $SPEED_THRESHOLD Mbps; maybe check if $INTERFACE is fully plugged into its socket.***"

            # Speed's not below the threshold            
            else
                logger -t hotplug "$SCRIPTNAME, Interface/Device $INTERFACE/$DEVICE switched on and running @ $SPEED Mbps." 
                echo -e "$INTERFACE switched on" $(date +"%F @ %H:%M:%S")", $DEVICE speed is $SPEED Mbps.\n" >> $LOGFILE  

                if [ "$INTERFACE" != "PS4" ]; then
                    send_email "$INTERFACE is up and running @ $SPEED Mbps."
                fi
            fi

            rm $COUNTER_UP_FILE
            rm $COUNTER_DOWN_FILE
        fi

elif [ "$ACTION" = "ifdown" ]; then
 
        if [ ! -f "$COUNTER_DOWN_FILE" ]; then

            echo 1 > "$COUNTER_DOWN_FILE"
            
            logger -t hotplug "$SCRIPTNAME, Interface/Device $INTERFACE/$DEVICE is down."
            echo -e "$INTERFACE is down on" $(date +"%F @ %H:%M:%S")" \n" >> $LOGFILE
            send_email "$INTERFACE is down."  

            # It was UP and goes DOWN
            if [ -f $INTERFACEON ]; then
                rm $INTERFACEON
                COUNT_DOWN=$(cat "$COUNTER_DOWN_FILE")
                COUNT_DOWN=$(($COUNT_DOWN + 1))
            fi
        
        else
            COUNT_DOWN=$(cat "$COUNTER_DOWN_FILE")
            COUNT_DOWN=$(($COUNT_DOWN + 1))
            echo "$COUNT_DOWN" > $COUNTER_DOWN_FILE
        fi
         
fi

Maybe it'll require some fine-tuning, but.. going to celebrate.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.