diff options
| author | Jo-Philipp Wich | 2023-08-24 12:43:31 +0000 |
|---|---|---|
| committer | Jo-Philipp Wich | 2023-11-08 08:49:57 +0000 |
| commit | 5c2e5d5ea4e0dd9a0ed66154d818b96bf81664f4 (patch) | |
| tree | c21f438027e4922a734d092826c2b9cdc4563284 | |
| parent | 76eb342c397a90feb77b54be2706fa9ff61637f1 (diff) | |
| download | netifd-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.c | 16 | ||||
| -rw-r--r-- | interface-ip.h | 3 | ||||
| -rw-r--r-- | system-linux.c | 3 |
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; |