diff options
| author | Michael Biebl <biebl@debian.org> | 2026-02-22 00:40:03 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2026-02-22 00:40:03 +0100 |
| commit | ccdb9117cca7141ee709afca8b25c966ff4fa18e (patch) | |
| tree | 3b7377c95e1d4049c13dd9101ae923fee70ab91d /src/libnm-platform/nm-linux-platform.c | |
| parent | d0ea10125cc04f55c1864451198d87fb801d1457 (diff) | |
| parent | 067fb576988f685e83ac8b0ae690334aff547c85 (diff) | |
Update upstream source from tag 'upstream/1.56.0'
Update to upstream version '1.56.0' with Debian dir 15fab61a7abf1fd4e2ba46785f96d935e87d32bb
Diffstat (limited to 'src/libnm-platform/nm-linux-platform.c')
| -rw-r--r-- | src/libnm-platform/nm-linux-platform.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 0c1097c2..cc5b99e0 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -59,6 +59,7 @@ G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_SUBFLOW == MPTCP_PM_ADDR_FLAG_SUBFLOW); G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_BACKUP == MPTCP_PM_ADDR_FLAG_BACKUP); G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_FULLMESH == MPTCP_PM_ADDR_FLAG_FULLMESH); G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_IMPLICIT == MPTCP_PM_ADDR_FLAG_IMPLICIT); +G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_LAMINAR == MPTCP_PM_ADDR_FLAG_LAMINAR); /*****************************************************************************/ @@ -4014,6 +4015,7 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter [RTA_PREF] = {.type = NLA_U8}, [RTA_FLOW] = {.type = NLA_U32}, [RTA_CACHEINFO] = {.minlen = nm_offsetofend(struct rta_cacheinfo, rta_tsage)}, + [RTA_VIA] = {.minlen = nm_offsetofend(struct rtvia, rtvia_family)}, [RTA_METRICS] = {.type = NLA_NESTED}, [RTA_MULTIPATH] = {.type = NLA_NESTED}, }; @@ -4030,9 +4032,11 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter guint8 weight; int ifindex; NMIPAddr gateway; + gboolean is_via; } nh = { .found = FALSE, .has_more = FALSE, + .is_via = FALSE, }; guint v4_n_nexthops = 0; NMPlatformIP4RtNextHop v4_nh_extra_nexthops_stack[10]; @@ -4201,13 +4205,26 @@ rta_multipath_done: return nm_assert_unreachable_val(NULL); } - if (tb[RTA_OIF] || tb[RTA_GATEWAY] || tb[RTA_FLOW]) { + if (tb[RTA_OIF] || tb[RTA_GATEWAY] || tb[RTA_FLOW] || tb[RTA_VIA]) { int ifindex = 0; NMIPAddr gateway = {}; if (tb[RTA_OIF]) ifindex = nla_get_u32(tb[RTA_OIF]); - if (_check_addr_or_return_null(tb, RTA_GATEWAY, addr_len)) + + if (tb[RTA_VIA]) { + struct rtvia *rtvia; + + /* Used when the gateway family doesn't match the route family */ + rtvia = nla_data(tb[RTA_VIA]); + if (rtvia->rtvia_family != AF_INET6) + return NULL; + if (nla_len(tb[RTA_VIA]) < sizeof(struct rtvia) + sizeof(struct in6_addr)) + return NULL; + + nh.is_via = TRUE; + memcpy(&gateway, rtvia->rtvia_addr, sizeof(struct in6_addr)); + } else if (_check_addr_or_return_null(tb, RTA_GATEWAY, addr_len)) memcpy(&gateway, nla_data(tb[RTA_GATEWAY]), addr_len); if (!nh.found) { @@ -4223,6 +4240,9 @@ rta_multipath_done: } else { /* Kernel supports new style nexthop configuration, * verify that it is a duplicate and ignore old-style nexthop. */ + if (nh.is_via) + return NULL; + if (nh.ifindex != ifindex || memcmp(&nh.gateway, &gateway, addr_len) != 0) { /* we have a RTA_MULTIPATH attribute that does not agree. * That seems not right. Error out. */ @@ -4238,7 +4258,7 @@ rta_multipath_done: * 1 (lo). Of course it does!! */ if (nh.found) { if (IS_IPv4) { - if (nh.ifindex != 0 || nh.gateway.addr4 != 0) { + if (nh.ifindex != 0 || nh.gateway.addr4 != 0 || nh.is_via) { /* we only accept kernel to notify about the ifindex/gateway, if it * is zero. This is only to be a bit forgiving, but we really don't * know how to handle such routes that have an ifindex. */ @@ -4337,9 +4357,14 @@ rta_multipath_done: if (tb[RTA_PRIORITY]) obj->ip_route.metric = nla_get_u32(tb[RTA_PRIORITY]); - if (IS_IPv4) - obj->ip4_route.gateway = nh.gateway.addr4; - else + if (IS_IPv4) { + if (nh.is_via) { + obj->ip4_route.via.addr_family = AF_INET6; + obj->ip4_route.via.addr = nh.gateway; + } else { + obj->ip4_route.gateway = nh.gateway.addr4; + } + } else obj->ip6_route.gateway = nh.gateway.addr6; if (IS_IPv4) @@ -5838,7 +5863,24 @@ _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 == INADDR_ANY && obj->ip4_route.via.addr_family != AF_UNSPEC) { + struct rtvia *rtvia; + + nm_assert(obj->ip4_route.via.addr_family == AF_INET6); + + 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); |