[PATCH v2 2/3] net: ifup: have ifup -a1 stop at first DHCP-set global.net.server

Ahmad Fatoum a.fatoum at pengutronix.de
Sun Jan 29 23:20:56 PST 2023


The normal use case for ifup -a is to get *some* interface working and
not really wait for all interfaces to come up and then timeout waiting
for those without link up to never get a DHCP lease.

When using automounts with a previously empty $global.net.server, we
know this to be the case, because the first DHCP interface will set the
variable and all remaining ones won't affect this. Therefore, let's add
a ifup -a1 option, which would stop after $global.net.server was set via
DHCP. This is a special case of a possible future ifup -ar, which would
check after each ifup if $global.net.server was either newly set or
became resolvable, but that would be a bigger change, so we skip that
for now.

Times after eth_open_all has brought up CPU Ethernet and 4 DSA ports:

  barebox$ time ifup -a
  time: 10002ms

  barebox$ time ifup -a1
  time: 1072ms

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
  - v1 -> v2:
    - add new option for this behavior instead of just -a
    - stop after global.net.server is set instead of just
      stopping after first upped interface
---
 include/net.h |  2 ++
 net/ifup.c    | 27 ++++++++++++++++++++++++---
 net/net.c     |  7 ++++++-
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/include/net.h b/include/net.h
index a7da282412fa..b7cbab7d720a 100644
--- a/include/net.h
+++ b/include/net.h
@@ -257,6 +257,7 @@ extern unsigned char *NetRxPackets[PKTBUFSRX];/* Receive packets		*/
 
 void net_set_ip(struct eth_device *edev, IPaddr_t ip);
 void net_set_serverip(IPaddr_t ip);
+const char *net_get_server(void);
 void net_set_serverip_empty(IPaddr_t ip);
 void net_set_netmask(struct eth_device *edev, IPaddr_t ip);
 void net_set_gateway(IPaddr_t ip);
@@ -514,6 +515,7 @@ void led_trigger_network(enum led_trigger trigger);
 #define IFUP_FLAG_FORCE		(1 << 0)
 #define IFUP_FLAG_PARALLEL	(1 << 1)
 #define IFUP_FLAG_SKIP_CONF	(1 << 2)
+#define IFUP_FLAG_UNTIL_NET_SERVER	(1 << 3)
 
 int ifup_edev(struct eth_device *edev, unsigned flags);
 int ifup(const char *name, unsigned flags);
diff --git a/net/ifup.c b/net/ifup.c
index c491ea03c1c8..64298b44ebf3 100644
--- a/net/ifup.c
+++ b/net/ifup.c
@@ -304,6 +304,9 @@ static void __ifup_all_parallel(unsigned flags)
 				continue;
 
 			netdev_count--;
+
+			if ((flags & IFUP_FLAG_UNTIL_NET_SERVER) && net_get_server())
+				return;
 		}
 	}
 }
@@ -312,8 +315,12 @@ static void __ifup_all_sequence(unsigned flags)
 {
 	struct eth_device *edev;
 
-	for_each_netdev(edev)
+	for_each_netdev(edev) {
 		ifup_edev(edev, flags);
+
+		if ((flags & IFUP_FLAG_UNTIL_NET_SERVER) && net_get_server())
+			return;
+	}
 }
 
 int ifup_all(unsigned flags)
@@ -340,6 +347,16 @@ int ifup_all(unsigned flags)
 	    list_empty(&netdev_list))
 		device_detect_all();
 
+	/*
+	 * In the future, we may add an iproute -r option that tries to
+	 * resolve $global.net.server using each interface. For now,
+	 * we only support the special case of $global.net.server being
+	 * empty, i.e. the first DHCP lease setting $global.net.server
+	 * will be what we're going with.
+	 */
+	if (net_get_server())
+		flags &= ~IFUP_FLAG_UNTIL_NET_SERVER;
+
 	if (flags & IFUP_FLAG_PARALLEL)
 		__ifup_all_parallel(flags);
 	else
@@ -375,11 +392,14 @@ static int do_ifup(int argc, char *argv[])
 	unsigned flags = IFUP_FLAG_PARALLEL;
 	int all = 0;
 
-	while ((opt = getopt(argc, argv, "asf")) > 0) {
+	while ((opt = getopt(argc, argv, "asf1")) > 0) {
 		switch (opt) {
 		case 'f':
 			flags |= IFUP_FLAG_FORCE;
 			break;
+		case '1':
+			flags |= IFUP_FLAG_UNTIL_NET_SERVER;
+			break;
 		case 's':
 			flags &= ~IFUP_FLAG_PARALLEL;
 			break;
@@ -408,12 +428,13 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-a",  "bring up all interfaces")
 BAREBOX_CMD_HELP_OPT ("-s",  "bring up interfaces in sequence, not in parallel")
 BAREBOX_CMD_HELP_OPT ("-f",  "Force. Configure even if ip already set")
+BAREBOX_CMD_HELP_OPT ("-1",  "Early exit if DHCP sets $global.net.server")
 BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(ifup)
 	.cmd		= do_ifup,
 	BAREBOX_CMD_DESC("bring a network interface up")
-	BAREBOX_CMD_OPTS("[-asf] [INTF]")
+	BAREBOX_CMD_OPTS("[-asf1] [INTF]")
 	BAREBOX_CMD_GROUP(CMD_GRP_NET)
 	BAREBOX_CMD_COMPLETE(eth_complete)
 	BAREBOX_CMD_HELP(cmd_ifup_help)
diff --git a/net/net.c b/net/net.c
index 22931509d0d9..19161d2e828e 100644
--- a/net/net.c
+++ b/net/net.c
@@ -325,9 +325,14 @@ void net_set_serverip(IPaddr_t ip)
 	net_server = xasprintf("%pI4", &ip);
 }
 
+const char *net_get_server(void)
+{
+	return net_server && *net_server ? net_server : NULL;
+}
+
 void net_set_serverip_empty(IPaddr_t ip)
 {
-	if (net_server && *net_server)
+	if (net_get_server())
 		return;
 
 	net_set_serverip(ip);
-- 
2.30.2




More information about the barebox mailing list