summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-02-28 08:39:27 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2014-03-07 07:41:36 +0100
commita162dfe50345d3461010759f8a0e79f7e388c140 (patch)
treed39aa64b4835fbf3af9a7466c3ec21839c841b24 /net
parent72dfc499c8ae272614d5b572b86b776e70778bbd (diff)
downloadbarebox-a162dfe50345d3461010759f8a0e79f7e388c140.tar.gz
barebox-a162dfe50345d3461010759f8a0e79f7e388c140.tar.xz
net: Add ifup support
The defaultenv-2 has ifup support as a shell script. This patch replaces it with a command which is more robust, can be called from C and now can also bring up all configured interfaces. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig11
-rw-r--r--net/Makefile1
-rw-r--r--net/ifup.c179
3 files changed, 191 insertions, 0 deletions
diff --git a/net/Kconfig b/net/Kconfig
index c12193db5c..59b64175de 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -26,4 +26,15 @@ config NET_RESOLV
bool
prompt "dns support"
+config NET_IFUP
+ default y
+ bool
+
+config NET_CMD_IFUP
+ bool
+ prompt "ifup support"
+ help
+ This enables the 'ifup' command which is used to bring up network
+ interfaces based on config files under /env/network/<ethname>
+
endif
diff --git a/net/Makefile b/net/Makefile
index 416e30ac35..fabb17e4a8 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_NET_NFS) += nfs.o
obj-$(CONFIG_NET_PING) += ping.o
obj-$(CONFIG_NET_RESOLV)+= dns.o
obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o
+obj-$(CONFIG_NET_IFUP) += ifup.o
diff --git a/net/ifup.c b/net/ifup.c
new file mode 100644
index 0000000000..3b89ce1bc2
--- /dev/null
+++ b/net/ifup.c
@@ -0,0 +1,179 @@
+/*
+ * ifup.c - bring up network interfaces
+ *
+ * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more detaiifup.
+ *
+ */
+#define pr_fmt(fmt) "ifup: " fmt
+
+#include <environment.h>
+#include <command.h>
+#include <common.h>
+#include <getopt.h>
+#include <net.h>
+#include <fs.h>
+#include <linux/stat.h>
+
+static char *vars[] = {
+ "ipaddr",
+ "netmask",
+ "gateway",
+ "serverip",
+ "ethaddr",
+};
+
+static int eth_set_param(struct device_d *dev, const char *param)
+{
+ const char *value = getenv(param);
+
+ if (!value)
+ return 0;
+ if (!*value)
+ return 0;
+
+ return dev_set_param(dev, param, value);
+}
+
+int ifup(const char *name, unsigned flags)
+{
+ int ret;
+ char *cmd, *cmd_discover;
+ const char *ip;
+ struct stat s;
+ int i;
+ struct device_d *dev;
+ struct eth_device *edev = eth_get_byname(name);
+
+ if (edev && edev->ipaddr && !(flags & IFUP_FLAG_FORCE))
+ return 0;
+
+ env_push_context();
+
+ setenv("ip", "");
+
+ for (i = 0; i < ARRAY_SIZE(vars); i++)
+ setenv(vars[i], "");
+
+ cmd = asprintf("source /env/network/%s", name);
+ cmd_discover = asprintf("/env/network/%s-discover", name);
+
+ ret = run_command(cmd);
+ if (ret)
+ goto out;
+
+ ret = stat(cmd_discover, &s);
+ if (!ret) {
+ ret = run_command(cmd_discover);
+ if (ret)
+ goto out;
+ }
+
+ dev = get_device_by_name(name);
+ if (!dev) {
+ pr_err("Cannot find device %s\n", name);
+ goto out;
+ }
+
+ ret = eth_set_param(dev, "ethaddr");
+ if (ret)
+ goto out;
+
+ ip = getenv("ip");
+ if (!strcmp(ip, "dhcp")) {
+ ret = run_command("dhcp");
+ if (ret)
+ goto out;
+ } else if (!strcmp(ip, "static")) {
+ for (i = 0; i < ARRAY_SIZE(vars); i++) {
+ ret = eth_set_param(dev, vars[i]);
+ if (ret)
+ goto out;
+ }
+ } else {
+ pr_err("unknown ip type: %s\n", ip);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ env_pop_context();
+ free(cmd);
+ free(cmd_discover);
+
+ return ret;
+}
+
+int ifup_all(unsigned flags)
+{
+ DIR *dir;
+ struct dirent *d;
+
+ dir = opendir("/env/network");
+ if (!dir)
+ return -ENOENT;
+
+ while ((d = readdir(dir))) {
+ if (*d->d_name == '.')
+ continue;
+ ifup(d->d_name, flags);
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_NET_CMD_IFUP)
+
+static int do_ifup(int argc, char *argv[])
+{
+ int opt;
+ unsigned flags = 0;
+ int all = 0;
+
+ while ((opt = getopt(argc, argv, "af")) > 0) {
+ switch (opt) {
+ case 'f':
+ flags |= IFUP_FLAG_FORCE;
+ break;
+ case 'a':
+ all = 1;
+ break;
+ }
+ }
+
+ if (all)
+ return ifup_all(flags);
+
+ if (argc == optind)
+ return COMMAND_ERROR_USAGE;
+
+ return ifup(argv[optind], flags);
+}
+
+BAREBOX_CMD_HELP_START(ifup)
+BAREBOX_CMD_HELP_USAGE("ifup [OPTIONS] <interface>\n")
+BAREBOX_CMD_HELP_OPT ("-a", "bring up all interfaces\n")
+BAREBOX_CMD_HELP_OPT ("-f", "Force. Configure even if ip already set\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(ifup)
+ .cmd = do_ifup,
+ .usage = "Bring up network interfaces",
+ BAREBOX_CMD_HELP(cmd_ifup_help)
+BAREBOX_CMD_END
+
+#endif