summaryrefslogtreecommitdiffstats
path: root/net
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 /net
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>
Diffstat (limited to 'net')
-rw-r--r--net/net.c30
1 files changed, 28 insertions, 2 deletions
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)) {