diff options
| author | Michael Biebl <biebl@debian.org> | 2026-05-14 19:21:22 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2026-05-14 19:21:22 +0200 |
| commit | 869e9027026cdbb15d4e4a6327ff41d2697858eb (patch) | |
| tree | 52edec7f935ff1bbb425c3515c6e49e6b8b0e28b /src/libnm-platform | |
| parent | 067fb576988f685e83ac8b0ae690334aff547c85 (diff) | |
New upstream version 1.56.1 upstream/1.56.1
Diffstat (limited to 'src/libnm-platform')
| -rw-r--r-- | src/libnm-platform/nm-linux-platform.c | 131 | ||||
| -rw-r--r-- | src/libnm-platform/nm-platform.c | 109 | ||||
| -rw-r--r-- | src/libnm-platform/nm-platform.h | 45 | ||||
| -rw-r--r-- | src/libnm-platform/nmp-base.h | 7 | ||||
| -rw-r--r-- | src/libnm-platform/nmp-object.c | 12 | ||||
| -rw-r--r-- | src/libnm-platform/nmp-object.h | 8 | ||||
| -rw-r--r-- | src/libnm-platform/tests/test-nm-platform.c | 2 |
7 files changed, 279 insertions, 35 deletions
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index cc5b99e0..b5df8b17 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -862,6 +862,7 @@ static const LinkDesc link_descs[] = { [NM_LINK_TYPE_BNEP] = {"bluetooth", NULL, "bluetooth"}, [NM_LINK_TYPE_DUMMY] = {"dummy", "dummy", NULL}, + [NM_LINK_TYPE_GENEVE] = {"geneve", "geneve", "geneve"}, [NM_LINK_TYPE_GRE] = {"gre", "gre", NULL}, [NM_LINK_TYPE_GRETAP] = {"gretap", "gretap", NULL}, [NM_LINK_TYPE_IFB] = {"ifb", "ifb", NULL}, @@ -909,6 +910,7 @@ _link_type_from_rtnl_type(const char *name) NM_LINK_TYPE_BOND, /* "bond" */ NM_LINK_TYPE_BRIDGE, /* "bridge" */ NM_LINK_TYPE_DUMMY, /* "dummy" */ + NM_LINK_TYPE_GENEVE, /* "geneve" */ NM_LINK_TYPE_GRE, /* "gre" */ NM_LINK_TYPE_GRETAP, /* "gretap" */ NM_LINK_TYPE_HSR, /* "hsr" */ @@ -987,6 +989,7 @@ _link_type_from_devtype(const char *name) NM_LINK_TYPE_BNEP, /* "bluetooth" */ NM_LINK_TYPE_BOND, /* "bond" */ NM_LINK_TYPE_BRIDGE, /* "bridge" */ + NM_LINK_TYPE_GENEVE, /* "geneve" */ NM_LINK_TYPE_HSR, /* "hsr" */ NM_LINK_TYPE_PPP, /* "ppp" */ NM_LINK_TYPE_VLAN, /* "vlan" */ @@ -1857,6 +1860,57 @@ _parse_lnk_gre(const char *kind, struct nlattr *info_data) /*****************************************************************************/ static NMPObject * +_parse_lnk_geneve(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_GENEVE_ID] = {.type = NLA_U32}, + [IFLA_GENEVE_REMOTE] = {.type = NLA_U32}, + [IFLA_GENEVE_REMOTE6] = {.type = NLA_UNSPEC, .minlen = sizeof(struct in6_addr)}, + [IFLA_GENEVE_TTL] = {.type = NLA_U8}, + [IFLA_GENEVE_TOS] = {.type = NLA_U8}, + [IFLA_GENEVE_TTL_INHERIT] = {.type = NLA_U8}, + [IFLA_GENEVE_PORT] = {.type = NLA_U16}, + [IFLA_GENEVE_DF] = {.type = NLA_U8}, + }; + + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; + NMPlatformLnkGeneve *props; + + if (!info_data || !nm_streq0(kind, "geneve")) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_GENEVE, NULL); + props = &obj->lnk_geneve; + + if (tb[IFLA_GENEVE_ID]) + props->id = nla_get_u32(tb[IFLA_GENEVE_ID]); + if (tb[IFLA_GENEVE_REMOTE]) + props->remote = nla_get_u32(tb[IFLA_GENEVE_REMOTE]); + if (tb[IFLA_GENEVE_REMOTE6]) + props->remote6 = *nla_data_as(struct in6_addr, tb[IFLA_GENEVE_REMOTE6]); + + if (tb[IFLA_GENEVE_TTL_INHERIT] && nla_get_u8(tb[IFLA_GENEVE_TTL_INHERIT])) + props->ttl = -1; + else if (tb[IFLA_GENEVE_TTL]) + props->ttl = nla_get_u8(tb[IFLA_GENEVE_TTL]); + + if (tb[IFLA_GENEVE_TOS]) + props->tos = nla_get_u8(tb[IFLA_GENEVE_TOS]); + if (tb[IFLA_GENEVE_PORT]) + props->dst_port = ntohs(nla_get_u16(tb[IFLA_GENEVE_PORT])); + if (tb[IFLA_GENEVE_DF]) + props->df = nla_get_u8(tb[IFLA_GENEVE_DF]); + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * _parse_lnk_hsr(const char *kind, struct nlattr *info_data) { static const struct nla_policy policy[] = { @@ -3694,6 +3748,9 @@ _new_from_nl_link(NMPlatform *platform, case NM_LINK_TYPE_BOND: lnk_data = _parse_lnk_bond(nl_info_kind, nl_info_data); break; + case NM_LINK_TYPE_GENEVE: + lnk_data = _parse_lnk_geneve(nl_info_kind, nl_info_data); + break; case NM_LINK_TYPE_GRE: case NM_LINK_TYPE_GRETAP: lnk_data = _parse_lnk_gre(nl_info_kind, nl_info_data); @@ -4033,6 +4090,7 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter int ifindex; NMIPAddr gateway; gboolean is_via; + unsigned rtnh_flags; } nh = { .found = FALSE, .has_more = FALSE, @@ -4142,9 +4200,10 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter v4_nh_extra_nexthops = v4_nh_extra_nexthops_heap; } nm_assert(v4_n_nexthops - 1u < v4_nh_extra_alloc); - new_nexthop = &v4_nh_extra_nexthops[v4_n_nexthops - 1u]; - new_nexthop->ifindex = rtnh->rtnh_ifindex; - new_nexthop->weight = NM_MAX(((guint) rtnh->rtnh_hops) + 1u, 1u); + new_nexthop = &v4_nh_extra_nexthops[v4_n_nexthops - 1u]; + new_nexthop->ifindex = rtnh->rtnh_ifindex; + new_nexthop->weight = NM_MAX(((guint) rtnh->rtnh_hops) + 1u, 1u); + new_nexthop->rtnh_flags = rtnh->rtnh_flags; if (rtnh->rtnh_len > sizeof(*rtnh)) { struct nlattr *ntb[RTA_MAX + 1]; @@ -4159,9 +4218,10 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter memcpy(&new_nexthop->gateway, nla_data(ntb[RTA_GATEWAY]), addr_len); } } else if (IS_IPv4 || idx == multihop_idx) { - nh.found = TRUE; - nh.ifindex = rtnh->rtnh_ifindex; - nh.weight = NM_MAX(((guint) rtnh->rtnh_hops) + 1u, 1u); + nh.found = TRUE; + nh.ifindex = rtnh->rtnh_ifindex; + nh.weight = NM_MAX(((guint) rtnh->rtnh_hops) + 1u, 1u); + nh.rtnh_flags = rtnh->rtnh_flags; if (rtnh->rtnh_len > sizeof(*rtnh)) { struct nlattr *ntb[RTA_MAX + 1]; @@ -4409,7 +4469,16 @@ rta_multipath_done: } obj->ip_route.r_rtm_flags = rtm->rtm_flags; - obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot(rtm->rtm_protocol); + + if (IS_IPv4 && v4_n_nexthops > 1u) { + /* For multipath routes, rtm_flags at the route level does not contain + * RTNH_F_ONLINK. Instead, each nexthop has its own rtnh_flags. Merge the + * first nexthop's RTNH_F_ONLINK into r_rtm_flags, since the first nexthop + * is embedded in the route struct. */ + obj->ip_route.r_rtm_flags |= (nh.rtnh_flags & RTNH_F_ONLINK); + } + + obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot(rtm->rtm_protocol); if (nh.has_more) { parse_nlmsg_iter->iter_more = TRUE; @@ -5182,6 +5251,35 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo nla_nest_end(msg, info_peer); break; } + case NM_LINK_TYPE_GENEVE: + { + const NMPlatformLnkGeneve *props = extra_data; + + nm_assert(props); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U32(msg, IFLA_GENEVE_ID, props->id); + + if (props->remote) { + NLA_PUT_U32(msg, IFLA_GENEVE_REMOTE, props->remote); + } else if (!IN6_IS_ADDR_UNSPECIFIED(&props->remote6)) { + NLA_PUT(msg, IFLA_GENEVE_REMOTE6, sizeof(props->remote6), &props->remote6); + } + NLA_PUT_U16(msg, IFLA_GENEVE_PORT, htons(props->dst_port)); + if (props->ttl == -1) { + NLA_PUT_U8(msg, IFLA_GENEVE_TTL_INHERIT, 1); + } else { + /* When you want to specify a TTL value, + * don't add TTL_INHERIT to the message */ + NLA_PUT_U8(msg, IFLA_GENEVE_TTL, props->ttl & 0xff); + } + NLA_PUT_U8(msg, IFLA_GENEVE_TOS, props->tos); + NLA_PUT_U8(msg, IFLA_GENEVE_DF, props->df); + break; + } + case NM_LINK_TYPE_GRE: case NM_LINK_TYPE_GRETAP: { @@ -5813,15 +5911,18 @@ _nl_msg_new_route(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPObject *ob } NLA_PUT_U32(msg, RTA_GATEWAY, gw); - rtnh->rtnh_flags = 0; + if (i == 0u) { + rtnh->rtnh_flags = + (gw != 0 && NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, (unsigned) RTNH_F_ONLINK)) + ? RTNH_F_ONLINK + : 0; + } else { + const NMPlatformIP4RtNextHop *n2 = &obj->_ip4_route.extra_nexthops[i - 1u]; - if (obj->ip4_route.n_nexthops > 1 - && NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, (unsigned) (RTNH_F_ONLINK)) && gw != 0) { - /* Unlike kernel, we only track the onlink flag per NMPlatformIP4Address, and - * not per nexthop. That is fine for NetworkManager configuring addresses. - * It is not fine for tracking addresses from kernel in platform cache, - * because the rtnh_flags of the nexthops need to be part of nmp_object_id_cmp(). */ - rtnh->rtnh_flags |= RTNH_F_ONLINK; + rtnh->rtnh_flags = + (gw != 0 && NM_FLAGS_HAS(n2->rtnh_flags, (unsigned) RTNH_F_ONLINK)) + ? RTNH_F_ONLINK + : 0; } rtnh->rtnh_len = (char *) nlmsg_tail(nlmsg_hdr(msg)) - (char *) rtnh; diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 853157d2..914dcd86 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -1388,6 +1388,12 @@ nm_platform_link_add(NMPlatform *self, case NM_LINK_TYPE_VETH: nm_sprintf_buf(buf, ", veth-peer \"%s\"", (const char *) extra_data); break; + case NM_LINK_TYPE_GENEVE: + nm_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_geneve_to_string((const NMPlatformLnkGeneve *) extra_data, + buf_p, + buf_len); + break; case NM_LINK_TYPE_GRE: case NM_LINK_TYPE_GRETAP: nm_strbuf_append_str(&buf_p, &buf_len, ", "); @@ -2565,6 +2571,12 @@ nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformL return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BRIDGE, out_link); } +const NMPlatformLnkGeneve * +nm_platform_link_get_lnk_geneve(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GENEVE, out_link); +} + const NMPlatformLnkGre * nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -6495,6 +6507,52 @@ nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize le } const char * +nm_platform_lnk_geneve_to_string(const NMPlatformLnkGeneve *lnk, char *buf, gsize len) +{ + char str_remote[NM_INET_ADDRSTRLEN]; + char str_remote1[30 + NM_INET_ADDRSTRLEN]; + char str_remote6[NM_INET_ADDRSTRLEN]; + char str_remote6_1[30 + NM_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_id[30]; + char str_dstport[30]; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf( + buf, + len, + "geneve" + "%s" /* id */ + "%s" /* remote */ + "%s" /* remote6 */ + "%s" /* dst_port */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* df */ + "", + lnk->id ? nm_sprintf_buf(str_id, " id %u", lnk->id) : "", + lnk->remote + ? nm_sprintf_buf(str_remote, " remote %s", nm_inet4_ntop(lnk->remote, str_remote1)) + : "", + !IN6_IS_ADDR_UNSPECIFIED(&lnk->remote6) + ? nm_sprintf_buf(str_remote6, " remote %s", nm_inet6_ntop(&lnk->remote6, str_remote6_1)) + : "", + lnk->dst_port ? nm_sprintf_buf(str_dstport, " dstport %u", lnk->dst_port) : "", + lnk->ttl > 0 ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl & 0xff) + : lnk->ttl == 0 ? "ttl auto" + : "ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos)) + : "", + lnk->df == 1 ? " df set " + : lnk->df == 2 ? " df inherit " + : ""); + return buf; +} + +const char * nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len) { char str_local[30]; @@ -7366,13 +7424,16 @@ nm_platform_ip4_route_to_string_full(const NMPlatformIP4Route *route, "%s" /* ifindex */ "%s%s" /* gateway */ " weight %s" /* weight */ + "%s" /* onlink */ "", NM_PRINT_FMT_QUOTED2(nexthop->gateway != 0 || nexthop->ifindex <= 0, " via ", nm_inet4_ntop(nexthop->gateway, s_gateway), ""), _to_string_dev(str_dev, nexthop->ifindex), - nm_sprintf_buf(weight_str, "%u", nexthop->weight)); + nm_sprintf_buf(weight_str, "%u", nexthop->weight), + NM_FLAGS_HAS(nexthop->rtnh_flags, (unsigned) RTNH_F_ONLINK) ? " onlink" + : ""); } } } @@ -8492,6 +8553,27 @@ nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) } void +nm_platform_lnk_geneve_hash_update(const NMPlatformLnkGeneve *obj, NMHashState *h) +{ + nm_hash_update_vals(h, obj->id, obj->remote, obj->dst_port, obj->ttl, obj->tos, obj->df); + nm_hash_update_mem(h, &obj->remote6, sizeof(obj->remote6)); +} + +int +nm_platform_lnk_geneve_cmp(const NMPlatformLnkGeneve *a, const NMPlatformLnkGeneve *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, id); + NM_CMP_FIELD(a, b, remote); + NM_CMP_FIELD_MEMCMP(a, b, remote6); + NM_CMP_FIELD(a, b, ttl); + NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD(a, b, dst_port); + NM_CMP_FIELD(a, b, df); + return 0; +} + +void nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h) { nm_hash_update_vals(h, @@ -8931,7 +9013,11 @@ nm_platform_ip4_rt_nexthop_hash_update(const NMPlatformIP4RtNextHop *obj, nm_assert(obj); w = for_id ? NM_MAX(obj->weight, 1u) : obj->weight; - nm_hash_update_vals(h, obj->ifindex, obj->gateway, w); + nm_hash_update_vals(h, + obj->ifindex, + obj->gateway, + w, + for_id ? (obj->rtnh_flags & RTNH_F_ONLINK) : obj->rtnh_flags); } void @@ -8968,7 +9054,6 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, obj->initrwnd, obj->mtu, obj->rto_min, - obj->r_rtm_flags & RTNH_F_ONLINK, NM_HASH_COMBINE_BOOLS(guint16, obj->quickack, obj->lock_window, @@ -8986,7 +9071,8 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, obj->via.addr_family == AF_INET6 ? obj->via.addr.addr6 : in6addr_any, obj->gateway, - _ip4_route_weight_normalize(n_nexthops, obj->weight, FALSE)); + _ip4_route_weight_normalize(n_nexthops, obj->weight, FALSE), + obj->r_rtm_flags & RTNH_F_ONLINK); } } break; @@ -9079,6 +9165,11 @@ nm_platform_ip4_rt_nexthop_cmp(const NMPlatformIP4RtNextHop *a, w_b = for_id ? NM_MAX(b->weight, 1u) : b->weight; NM_CMP_DIRECT(w_a, w_b); + if (for_id) + NM_CMP_DIRECT(a->rtnh_flags & RTNH_F_ONLINK, b->rtnh_flags & RTNH_F_ONLINK); + else + NM_CMP_FIELD(a, b, rtnh_flags); + return 0; } @@ -9119,12 +9210,6 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, NM_CMP_FIELD(a, b, mtu); NM_CMP_FIELD(a, b, rto_min); - /* Note that for NetworkManager, the onlink flag is only part of the entire route. - * For kernel, each next hop has it's own onlink flag (rtnh_flags). This means, - * we can only merge ECMP routes, if they agree with their onlink flag, and then - * all next hops are onlink (or not). */ - NM_CMP_DIRECT(a->r_rtm_flags & RTNH_F_ONLINK, b->r_rtm_flags & RTNH_F_ONLINK); - NM_CMP_FIELD_UNSAFE(a, b, quickack); NM_CMP_FIELD_UNSAFE(a, b, lock_window); NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); @@ -9143,6 +9228,10 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, NM_CMP_DIRECT(n_nexthops, nm_platform_ip4_route_get_n_nexthops(b)); NM_CMP_DIRECT(_ip4_route_weight_normalize(n_nexthops, a->weight, FALSE), _ip4_route_weight_normalize(n_nexthops, b->weight, FALSE)); + /* The onlink flag is per-nexthop. For the first nexthop it is in + * r_rtm_flags. For extra nexthops, it's compared via + * nm_platform_ip4_rt_nexthop_cmp(). */ + NM_CMP_DIRECT(a->r_rtm_flags & RTNH_F_ONLINK, b->r_rtm_flags & RTNH_F_ONLINK); } } break; diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 033dc515..ba37d3a2 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -287,7 +287,7 @@ guint _nm_platform_signal_id_get(NMPlatformSignalIdType signal_type); #define __NMPlatformIPRoute_COMMON \ __NMPlatformObjWithIfindex_COMMON; \ \ - /* rtnh_flags + /* rtm_flags and rtnh_flags * * Routes with rtm_flags RTM_F_CLONED are hidden by platform and * do not exist from the point-of-view of platform users. @@ -295,8 +295,15 @@ guint _nm_platform_signal_id_get(NMPlatformSignalIdType signal_type); * * NOTE: currently we ignore all flags except RTM_F_CLONED * and RTNH_F_ONLINK. - * We also may not properly consider the flags as part of the ID - * in route-cmp. */ \ + * + * For IPv4 routes, the RTNH_F_ONLINK flag here applies to the + * first nexthop (which is embedded in the route struct). Extra + * nexthops (NMPlatformIP4RtNextHop) each have their own + * rtnh_flags field. + * + * For single-hop routes, this field comes directly from + * rtm_flags. For multi-hop routes from kernel, the first + * nexthop's RTNH_F_ONLINK from rtnh_flags is merged here. */ \ unsigned r_rtm_flags; \ \ /* RTA_METRICS.RTAX_ADVMSS (iproute2: advmss) */ \ @@ -733,10 +740,10 @@ typedef struct { */ guint16 weight; - /* FIXME: each next hop in kernel also has a rtnh_flags (for example to - * set RTNH_F_ONLINK). As the next hop is part of the identifier of an - * IPv4 route, so is their flags. We must also track the flag, otherwise - * two routes that look different for kernel, get merged by platform cache. */ + /* Each next hop in kernel has its own rtnh_flags (for example to + * set RTNH_F_ONLINK). The flags are part of the identifier of a + * route. */ + unsigned rtnh_flags; } NMPlatformIP4RtNextHop; typedef struct { @@ -836,6 +843,16 @@ typedef struct { } _nm_alignas(NMPlatformObject) NMPlatformLnkBond; typedef struct { + struct in6_addr remote6; + in_addr_t remote; + guint32 id; + gint32 ttl; + guint16 dst_port; + guint8 tos; + guint8 df; +} _nm_alignas(NMPlatformObject) NMPlatformLnkGeneve; + +typedef struct { int parent_ifindex; in_addr_t local; in_addr_t remote; @@ -1859,6 +1876,15 @@ nm_platform_link_vxlan_add(NMPlatform *self, } static inline int +nm_platform_link_geneve_add(NMPlatform *self, + const char *name, + const NMPlatformLnkGeneve *props, + const NMPlatformLink **out_link) +{ + return nm_platform_link_add(self, NM_LINK_TYPE_GENEVE, name, 0, NULL, 0, 0, props, out_link); +} + +static inline int nm_platform_link_6lowpan_add(NMPlatform *self, const char *name, int parent, @@ -2143,6 +2169,8 @@ const NMPlatformLnkBond * nm_platform_link_get_lnk_bond(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkBridge * nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkGeneve * +nm_platform_link_get_lnk_geneve(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkGre * nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkGre * @@ -2482,6 +2510,7 @@ gboolean nm_platform_tc_sync(NMPlatform *self, const char *nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len); const char *nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize len); const char *nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len); +const char *nm_platform_lnk_geneve_to_string(const NMPlatformLnkGeneve *lnk, char *buf, gsize len); const char *nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len); const char *nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len); const char * @@ -2537,6 +2566,7 @@ nm_platform_mptcp_addr_to_string(const NMPlatformMptcpAddr *mptcp_addr, char *bu int nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b); int nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b); int nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b); +int nm_platform_lnk_geneve_cmp(const NMPlatformLnkGeneve *a, const NMPlatformLnkGeneve *b); int nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b); int nm_platform_lnk_hsr_cmp(const NMPlatformLnkHsr *a, const NMPlatformLnkHsr *b); int nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a, @@ -2612,6 +2642,7 @@ void nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj, NMHashState *h); void nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h); void nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h); +void nm_platform_lnk_geneve_hash_update(const NMPlatformLnkGeneve *obj, NMHashState *h); void nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h); void nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h); void nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h); diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h index f6656296..ae538f5b 100644 --- a/src/libnm-platform/nmp-base.h +++ b/src/libnm-platform/nmp-base.h @@ -166,6 +166,7 @@ typedef enum _nm_packed { NMP_OBJECT_TYPE_TFILTER, NMP_OBJECT_TYPE_LNK_BRIDGE, + NMP_OBJECT_TYPE_LNK_GENEVE, NMP_OBJECT_TYPE_LNK_GRE, NMP_OBJECT_TYPE_LNK_GRETAP, NMP_OBJECT_TYPE_LNK_HSR, @@ -194,15 +195,15 @@ typedef enum _nm_packed { NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1, } NMPObjectType; -static inline guint32 +static inline guint64 nmp_object_type_to_flags(NMPObjectType obj_type) { - G_STATIC_ASSERT_EXPR(NMP_OBJECT_TYPE_MAX < 32); + G_STATIC_ASSERT_EXPR(NMP_OBJECT_TYPE_MAX < 64); nm_assert(_NM_INT_NOT_NEGATIVE(obj_type)); nm_assert(obj_type < NMP_OBJECT_TYPE_MAX); - return ((guint32) 1u) << obj_type; + return ((guint64) 1u) << obj_type; } /*****************************************************************************/ diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index 56533c99..d73eb641 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -3469,6 +3469,18 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_bridge_hash_update, .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_bridge_cmp, }, + [NMP_OBJECT_TYPE_LNK_GENEVE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_GENEVE, + .sizeof_data = sizeof(NMPObjectLnkGeneve), + .sizeof_public = sizeof(NMPlatformLnkGeneve), + .obj_type_name = "geneve", + .lnk_link_type = NM_LINK_TYPE_GENEVE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_geneve_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_geneve_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_geneve_cmp, + }, [NMP_OBJECT_TYPE_LNK_GRE - 1] = { .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h index b526fc3b..a960c528 100644 --- a/src/libnm-platform/nmp-object.h +++ b/src/libnm-platform/nmp-object.h @@ -251,6 +251,10 @@ typedef struct { } NMPObjectLnkBond; typedef struct { + NMPlatformLnkGeneve _public; +} NMPObjectLnkGeneve; + +typedef struct { NMPlatformLnkGre _public; } NMPObjectLnkGre; @@ -383,6 +387,9 @@ struct _NMPObject { NMPlatformLnkBond lnk_bond; NMPObjectLnkBond _lnk_bond; + NMPlatformLnkGeneve lnk_geneve; + NMPObjectLnkGeneve _lnk_geneve; + NMPlatformLnkGre lnk_gre; NMPObjectLnkGre _lnk_gre; @@ -543,6 +550,7 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type) case NMP_OBJECT_TYPE_LNK_BRIDGE: case NMP_OBJECT_TYPE_LNK_BOND: + case NMP_OBJECT_TYPE_LNK_GENEVE: case NMP_OBJECT_TYPE_LNK_GRE: case NMP_OBJECT_TYPE_LNK_GRETAP: case NMP_OBJECT_TYPE_LNK_HSR: diff --git a/src/libnm-platform/tests/test-nm-platform.c b/src/libnm-platform/tests/test-nm-platform.c index 22148f8c..d087d66f 100644 --- a/src/libnm-platform/tests/test-nm-platform.c +++ b/src/libnm-platform/tests/test-nm-platform.c @@ -19,6 +19,7 @@ G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectIP6Route)) G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLink)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLnkBond)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLnkBridge)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLnkGeneve)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLnkGre)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLnkInfiniband)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPObjectLnkIp6Tnl)); @@ -49,6 +50,7 @@ G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformIPXRoute) G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLink)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLnkBond)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLnkBridge)); +G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLnkGeneve)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLnkGre)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLnkInfiniband)); G_STATIC_ASSERT(_nm_alignof(NMPlatformObject) == _nm_alignof(NMPlatformLnkIp6Tnl)); |