summaryrefslogtreecommitdiffstats
path: root/net/ifup.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ifup.c')
-rw-r--r--net/ifup.c281
1 files changed, 196 insertions, 85 deletions
diff --git a/net/ifup.c b/net/ifup.c
index 5113d13832..827c5c03d1 100644
--- a/net/ifup.c
+++ b/net/ifup.c
@@ -22,144 +22,255 @@
#include <command.h>
#include <common.h>
#include <getopt.h>
+#include <dhcp.h>
#include <net.h>
#include <fs.h>
+#include <globalvar.h>
+#include <string.h>
+#include <driver.h>
#include <linux/stat.h>
-static char *vars[] = {
- "ipaddr",
- "netmask",
- "gateway",
- "serverip",
-};
-
-static int eth_set_param(struct device_d *dev, const char *param)
+static int eth_discover(char *file)
{
- const char *value = getenv(param);
+ struct stat s;
+ int ret;
- if (!value)
- return 0;
- if (!*value)
- return 0;
+ ret = stat(file, &s);
+ if (ret) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = run_command(file);
+ if (ret) {
+ pr_err("Running '%s' failed with %d\n", file, ret);
+ goto out;
+ }
+
+out:
+ free(file);
- return dev_set_param(dev, param, value);
+ return ret;
}
-int ifup(const char *name, unsigned flags)
+static int eth_discover_ethname(const char *ethname)
{
- int ret;
- char *cmd, *cmd_discover;
- const char *ip;
+ return eth_discover(basprintf("/env/network/%s-discover", ethname));
+}
+
+static int eth_discover_file(const char *filename)
+{
+ return eth_discover(basprintf("/env/network/%s", filename));
+}
+
+static int source_env_network(struct eth_device *edev)
+{
+ char *vars[] = {
+ "ipaddr",
+ "netmask",
+ "gateway",
+ "serverip",
+ "ethaddr",
+ "ip",
+ "linuxdevname",
+ };
+ IPaddr_t ipaddr, netmask, gateway, serverip;
+ unsigned char ethaddr[6];
+ char *file, *cmd;
+ const char *ethaddrstr, *modestr, *linuxdevname;
+ int ret, mode, ethaddr_valid = 0, i;
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))
+ file = basprintf("/env/network/%s", edev->devname);
+ ret = stat(file, &s);
+ if (ret) {
+ free(file);
return 0;
+ }
- eth_set_current(edev);
+ dev_info(&edev->dev, "/env/network/%s is deprecated.\n"
+ "Use nv.dev.%s.* nvvars to configure your network device instead\n",
+ edev->devname, edev->devname);
env_push_context();
- setenv("ip", "");
-
for (i = 0; i < ARRAY_SIZE(vars); i++)
setenv(vars[i], "");
- cmd = basprintf("source /env/network/%s", name);
- cmd_discover = basprintf("/env/network/%s-discover", name);
-
+ cmd = basprintf("source /env/network/%s", edev->devname);
ret = run_command(cmd);
if (ret) {
pr_err("Running '%s' failed with %d\n", cmd, ret);
goto out;
}
- ret = stat(cmd_discover, &s);
- if (!ret) {
- ret = run_command(cmd_discover);
+ ipaddr = getenv_ip("ipaddr");
+ netmask = getenv_ip("netmask");
+ gateway = getenv_ip("gateway");
+ serverip = getenv_ip("serverip");
+ linuxdevname = getenv("linuxdevname");
+ ethaddrstr = getenv("ethaddr");
+ if (ethaddrstr && *ethaddrstr) {
+ ret = string_to_ethaddr(ethaddrstr, ethaddr);
if (ret) {
- pr_err("Running '%s' failed with %d\n", cmd, ret);
+ dev_err(&edev->dev, "Cannot parse ethaddr \"%s\"\n", ethaddrstr);
+ ret = -EINVAL;
goto out;
}
+ ethaddr_valid = 1;
}
- dev = get_device_by_name(name);
- if (!dev) {
- pr_err("Cannot find device %s\n", name);
+ modestr = getenv("ip");
+ if (!modestr) {
+ dev_err(&edev->dev, "No mode specified in \"ip\" variable\n");
+ ret = -EINVAL;
goto out;
}
- ret = eth_set_param(dev, "ethaddr");
- if (ret)
- goto out;
-
- ip = getenv("ip");
- if (!ip)
- ip = "";
-
- if (!strcmp(ip, "dhcp")) {
- ret = run_command("dhcp");
- if (ret)
- goto out;
- ret = eth_set_param(dev, "serverip");
- if (ret)
- goto out;
- dev_set_param(dev, "linux.bootargs", "ip=dhcp");
- } else if (!strcmp(ip, "static")) {
- char *bootarg;
- for (i = 0; i < ARRAY_SIZE(vars); i++) {
- ret = eth_set_param(dev, vars[i]);
- if (ret)
- goto out;
- }
- bootarg = basprintf("ip=%pI4:%pI4:%pI4:%pI4:::",
- &edev->ipaddr,
- &edev->serverip,
- &edev->gateway,
- &edev->netmask);
- dev_set_param(dev, "linux.bootargs", bootarg);
- free(bootarg);
+ if (!strcmp(modestr, "static")) {
+ mode = ETH_MODE_STATIC;
+ } else if (!strcmp(modestr, "dhcp")) {
+ mode = ETH_MODE_DHCP;
} else {
- pr_err("unknown ip type: %s\n", ip);
+ dev_err(&edev->dev, "Invalid ip mode \"%s\" found\n", modestr);
ret = -EINVAL;
goto out;
}
+ edev->global_mode = mode;
+
+ if (ethaddr_valid)
+ memcpy(edev->ethaddr, ethaddr, 6);
+
+ if (mode == ETH_MODE_STATIC) {
+ edev->ipaddr = ipaddr;
+ edev->netmask = netmask;
+ if (gateway)
+ net_set_gateway(gateway);
+ if (serverip)
+ net_set_serverip(serverip);
+ }
+
+ if (linuxdevname) {
+ free(edev->linuxdevname);
+ edev->linuxdevname = xstrdup(linuxdevname);
+ }
+
ret = 0;
+
out:
env_pop_context();
free(cmd);
- free(cmd_discover);
+ free(file);
return ret;
}
+static void set_linux_bootarg(struct eth_device *edev)
+{
+ if (edev->global_mode == ETH_MODE_STATIC) {
+ char *bootarg;
+ IPaddr_t serverip;
+ IPaddr_t gateway;
+
+ serverip = net_get_serverip();
+ gateway = net_get_gateway();
+
+ bootarg = basprintf("ip=%pI4:%pI4:%pI4:%pI4::%s:",
+ &edev->ipaddr,
+ &serverip,
+ &gateway,
+ &edev->netmask,
+ edev->linuxdevname ? edev->linuxdevname : "");
+ dev_set_param(&edev->dev, "linux.bootargs", bootarg);
+ free(bootarg);
+ } else if (edev->global_mode == ETH_MODE_DHCP) {
+ dev_set_param(&edev->dev, "linux.bootargs", "ip=dhcp");
+ }
+}
+
+int ifup_edev(struct eth_device *edev, unsigned flags)
+{
+ int ret;
+
+ if (edev->global_mode == ETH_MODE_DISABLED) {
+ edev->ipaddr = 0;
+ edev->netmask = 0;
+ edev->ifup = false;
+ return 0;
+ }
+
+ if (edev->ifup) {
+ if (flags & IFUP_FLAG_FORCE)
+ edev->ifup = false;
+ else
+ return 0;
+ }
+
+ ret = source_env_network(edev);
+ if (ret)
+ return ret;
+
+ if (edev->global_mode == ETH_MODE_DHCP) {
+ if (IS_ENABLED(CONFIG_NET_DHCP)) {
+ ret = dhcp(edev, NULL);
+ } else {
+ dev_err(&edev->dev, "DHCP support not available\n");
+ ret = -ENOSYS;
+ }
+ if (ret)
+ return ret;
+ }
+
+ set_linux_bootarg(edev);
+
+ edev->ifup = true;
+
+ return 0;
+}
+
+int ifup(const char *ethname, unsigned flags)
+{
+ struct eth_device *edev;
+ int ret;
+
+ ret = eth_discover_ethname(ethname);
+ if (ret)
+ return ret;
+
+ edev = eth_get_byname(ethname);
+ if (!edev)
+ return -ENODEV;
+
+ return ifup_edev(edev, flags);
+}
+
int ifup_all(unsigned flags)
{
+ struct eth_device *edev;
DIR *dir;
struct dirent *d;
dir = opendir("/env/network");
- if (!dir)
- return -ENOENT;
-
- while ((d = readdir(dir))) {
- if (*d->d_name == '.')
- continue;
- /*
- * Skip xxx-discover files since these are no
- * network configuration files, but scripts to bring
- * up network interface xxx.
- */
- if (strstr(d->d_name, "-discover"))
- continue;
- ifup(d->d_name, flags);
+ if (dir) {
+
+ while ((d = readdir(dir))) {
+ if (*d->d_name == '.')
+ continue;
+ if (!strstr(d->d_name, "-discover"))
+ continue;
+
+ eth_discover_file(d->d_name);
+ }
}
closedir(dir);
+ device_detect_all();
+
+ for_each_netdev(edev)
+ ifup_edev(edev, flags);
+
return 0;
}
@@ -191,11 +302,11 @@ static int do_ifup(int argc, char *argv[])
return ifup(argv[optind], flags);
}
+
+
BAREBOX_CMD_HELP_START(ifup)
-BAREBOX_CMD_HELP_TEXT("Each INTF must have a script /env/network/INTF that set the variables")
-BAREBOX_CMD_HELP_TEXT("ip (to 'static' or 'dynamic'), ipaddr, netmask, gateway, serverip and/or")
-BAREBOX_CMD_HELP_TEXT("ethaddr. A script /env/network/INTF-discover can contains for discovering")
-BAREBOX_CMD_HELP_TEXT("the ethernet device, e.g. 'usb'.")
+BAREBOX_CMD_HELP_TEXT("Network interfaces are configured with a NV variables or a")
+BAREBOX_CMD_HELP_TEXT("/env/network/<intf> file. See Documentation/user/networking.rst")
BAREBOX_CMD_HELP_TEXT("")
BAREBOX_CMD_HELP_TEXT("Options:")
BAREBOX_CMD_HELP_OPT ("-a", "bring up all interfaces")