summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJo-Philipp Wich2023-08-24 12:43:31 +0000
committerJo-Philipp Wich2023-11-08 08:49:57 +0000
commit5c2e5d5ea4e0dd9a0ed66154d818b96bf81664f4 (patch)
treec21f438027e4922a734d092826c2b9cdc4563284
parent76eb342c397a90feb77b54be2706fa9ff61637f1 (diff)
downloadnetifd-5c2e5d5ea4e0dd9a0ed66154d818b96bf81664f4.tar.gz
interface-ip: allow configuring routes without explicit interface
Support the configuration of network routes not bound to any specific interface. In case such a route is configured, it will be internally owned by the loopback interface and have a new DEVROUTE_NODEV flag set to inhibit the RTA_OIF attribute when installing the kernel route. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--interface-ip.c16
-rw-r--r--interface-ip.h3
-rw-r--r--system-linux.c3
3 files changed, 18 insertions, 4 deletions
diff --git a/interface-ip.c b/interface-ip.c
index fee29a9..d2fe385 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -405,6 +405,7 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
struct blob_attr *tb[__ROUTE_MAX], *cur;
struct device_route *route;
int af = v6 ? AF_INET6 : AF_INET;
+ bool no_device = false;
blobmsg_parse(route_attr, __ROUTE_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr));
@@ -412,10 +413,13 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
return;
if (!iface) {
- if ((cur = tb[ROUTE_INTERFACE]) == NULL)
- return;
+ if ((cur = tb[ROUTE_INTERFACE]) == NULL) {
+ iface = vlist_find(&interfaces, "loopback", iface, node);
+ no_device = true;
+ } else {
+ iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
+ }
- iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
if (!iface)
return;
@@ -520,7 +524,11 @@ interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
route->flags |= DEVROUTE_PROTO;
}
- interface_set_route_info(iface, route);
+ if (no_device)
+ route->flags |= DEVROUTE_NODEV;
+ else
+ interface_set_route_info(iface, route);
+
vlist_add(&ip->route, &route->node, route);
return;
diff --git a/interface-ip.h b/interface-ip.h
index 8843349..cc7efbd 100644
--- a/interface-ip.h
+++ b/interface-ip.h
@@ -51,6 +51,9 @@ enum device_addr_flags {
/* neighbor mac address */
DEVNEIGH_MAC = (1 << 11),
+
+ /* route specifies no device */
+ DEVROUTE_NODEV = (1 << 12),
};
union if_addr {
diff --git a/system-linux.c b/system-linux.c
index bb23404..9097f6a 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -3022,6 +3022,9 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
}
}
+ if (route->flags & DEVROUTE_NODEV)
+ dev = NULL;
+
msg = nlmsg_alloc_simple(cmd, flags);
if (!msg)
return -1;