summaryrefslogtreecommitdiff
path: root/src/network/networkd-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-manager.c')
-rw-r--r--src/network/networkd-manager.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index ab89c1bc47..46bcdff1cf 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -34,6 +34,7 @@
#include "def.h"
#include "virt.h"
#include "set.h"
+#include "local-addresses.h"
#include "networkd.h"
@@ -845,3 +846,40 @@ int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, uni
return 0;
}
+
+Link* manager_find_uplink(Manager *m, Link *exclude) {
+ _cleanup_free_ struct local_address *gateways = NULL;
+ int n, i;
+
+ assert(m);
+
+ /* Looks for a suitable "uplink", via black magic: an
+ * interface that is up and where the default route with the
+ * highest priority points to. */
+
+ n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
+ if (n < 0) {
+ log_warning_errno(n, "Failed to determine list of default gateways: %m");
+ return NULL;
+ }
+
+ for (i = 0; i < n; i++) {
+ Link *link;
+
+ link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
+ if (!link) {
+ log_debug("Weird, found a gateway for a link we don't now. Ignoring.");
+ continue;
+ }
+
+ if (link == exclude)
+ continue;
+
+ if (link->operstate < LINK_OPERSTATE_ROUTABLE)
+ continue;
+
+ return link;
+ }
+
+ return NULL;
+}