diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 64209b5321..45770de534 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -5828,7 +5828,22 @@ _nl_msg_new_route(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPObject *ob /* We currently don't have need for multi-hop routes... */ if (IS_IPv4) { - NLA_PUT(msg, RTA_GATEWAY, addr_len, &obj->ip4_route.gateway); + if (!obj->ip4_route.gateway && obj->ip4_route.via.addr_family) { + struct rtvia *rtvia; + + rtvia = nla_data(nla_reserve( + msg, + RTA_VIA, + sizeof(*rtvia) + nm_utils_addr_family_to_size(obj->ip4_route.via.addr_family))); + if (!rtvia) + goto nla_put_failure; + rtvia->rtvia_family = obj->ip4_route.via.addr_family; + memcpy(rtvia->rtvia_addr, + obj->ip4_route.via.addr.addr_ptr, + nm_utils_addr_family_to_size(obj->ip4_route.via.addr_family)); + } else { + NLA_PUT(msg, RTA_GATEWAY, addr_len, &obj->ip4_route.gateway); + } } else { if (!IN6_IS_ADDR_UNSPECIFIED(&obj->ip6_route.gateway)) NLA_PUT(msg, RTA_GATEWAY, addr_len, &obj->ip6_route.gateway); diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index e4ccb9b1cb..cd6c26e326 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -443,6 +443,12 @@ struct _NMPlatformIP4Route { * the first hop. */ in_addr_t gateway; + /* RTA_VIA. Part of the primary key for a route. Allows a gateway for a + * route to exist in a different address family. + * Only valid if: n_nexthops == 1, gateway == 0, via.family != 0 + */ + NMIPAddrTyped via; + /* RTA_PREFSRC (called "src" by iproute2). * * pref_src is part of the ID of an IPv4 route. When deleting a route, @@ -2404,6 +2410,14 @@ nm_platform_ip_route_get_gateway(int addr_family, const NMPlatformIPRoute *route return &((NMPlatformIP6Route *) route)->gateway; } +static inline const NMIPAddrTyped * +nm_platform_ip4_route_get_via(const NMPlatformIP4Route *route) +{ + nm_assert(route); + + return &route->via; +} + static inline gconstpointer nm_platform_ip_route_get_pref_src(int addr_family, const NMPlatformIPRoute *route) {