net: Protect net_state from reentrant net_loop()
authorLeonid Iziumtsev <leonid.iziumtsev@gmail.com>
Tue, 8 May 2018 13:55:50 +0000 (15:55 +0200)
committerJoe Hershberger <joe.hershberger@ni.com>
Wed, 13 Jun 2018 18:54:16 +0000 (13:54 -0500)
Global variable "net_state" is used in net_loop() state-machine.
But it happens that some times the net_loop() can be called
multiple times in the same call stack. For example when the
netconsole is enabled and we print the message while some other
net protocol is in action. Netconsole will overwrite the "net_state"
and that will break the logic for earlier started protocol.

To protect the state save and restore "net_state" variable each
time when we enter and exit net_loop().

Signed-off-by: Leonid Iziumtsev <leonid.iziumtsev@se.atlascopco.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
net/net.c

index a4932f46d905f51d0466983b2032a35b134e4e73..b4563a4cab1fbfbccf595ee40a5e865514d79884 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -393,6 +393,7 @@ void net_init(void)
 int net_loop(enum proto_t protocol)
 {
        int ret = -EINVAL;
+       enum net_loop_state prev_net_state = net_state;
 
        net_restarted = 0;
        net_dev_exists = 0;
@@ -430,6 +431,7 @@ restart:
        case 1:
                /* network not configured */
                eth_halt();
+               net_set_state(prev_net_state);
                return -ENODEV;
 
        case 2:
@@ -655,6 +657,7 @@ done:
        net_set_udp_handler(NULL);
        net_set_icmp_handler(NULL);
 #endif
+       net_set_state(prev_net_state);
        return ret;
 }