summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-02-03 14:37:18 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-12-14 14:30:18 +0100
commit4362c73ac768ad7218982fc1ccf8ae04285c27d1 (patch)
treed9d80f42b52326b4bd7d99f4ce097faeb4004eb0
parent528298b702a0ad238dd01b3497f7c0bb671bf7c9 (diff)
downloadbarebox-4362c73ac768ad7218982fc1ccf8ae04285c27d1.tar.gz
barebox-4362c73ac768ad7218982fc1ccf8ae04285c27d1.tar.xz
net: Pick network device based on IP settings
The IP/netmask/gateway settings contain all informations needed to pick the correct network device. This patch adds support for that and makes specifying the "current" network interface using the ethact command unnecessary. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--include/net.h1
-rw-r--r--net/net.c30
2 files changed, 29 insertions, 2 deletions
diff --git a/include/net.h b/include/net.h
index b7555c0de6..3faecff5d7 100644
--- a/include/net.h
+++ b/include/net.h
@@ -226,6 +226,7 @@ IPaddr_t net_get_serverip(void);
IPaddr_t net_get_gateway(void);
IPaddr_t net_get_nameserver(void);
const char *net_get_domainname(void);
+struct eth_device *net_route(IPaddr_t ip);
/* Do the work */
void net_poll(void);
diff --git a/net/net.c b/net/net.c
index 33d6e2c5b0..94954677c5 100644
--- a/net/net.c
+++ b/net/net.c
@@ -144,6 +144,27 @@ static void arp_handler(struct arprequest *arp)
}
}
+struct eth_device *net_route(IPaddr_t dest)
+{
+ struct eth_device *edev;
+
+ for_each_netdev(edev) {
+ if (!edev->ipaddr)
+ continue;
+
+ if ((dest & edev->netmask) == (edev->ipaddr & edev->netmask)) {
+ pr_debug("Route: Using %s (ip=%pI4, nm=%pI4) to reach %pI4\n",
+ dev_name(&edev->dev), &edev->ipaddr, &edev->netmask,
+ &dest);
+ return edev;
+ }
+ }
+
+ pr_debug("Route: No device found for %pI4\n", &dest);
+
+ return NULL;
+}
+
static int arp_request(struct eth_device *edev, IPaddr_t dest, unsigned char *ether)
{
char *pkt;
@@ -154,6 +175,9 @@ static int arp_request(struct eth_device *edev, IPaddr_t dest, unsigned char *et
unsigned retries = 0;
int ret;
+ if (!edev)
+ return -EHOSTUNREACH;
+
if (!arp_packet) {
arp_packet = net_alloc_packet();
if (!arp_packet)
@@ -295,9 +319,11 @@ static struct net_connection *net_new(struct eth_device *edev, IPaddr_t dest,
int ret;
if (!edev) {
- edev = eth_get_current();
+ edev = net_route(dest);
+ if (!edev && net_gateway)
+ edev = net_route(net_gateway);
if (!edev)
- return ERR_PTR(-ENETDOWN);
+ return ERR_PTR(-EHOSTUNREACH);
}
if (!is_valid_ether_addr(edev->ethaddr)) {