about summary refs log tree commit diff
path: root/src/libnm-platform/nm-linux-platform.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2025-08-01 19:15:18 +0200
committerMichael Biebl <biebl@debian.org>2025-08-01 19:15:18 +0200
commit43a9f1ee48d7f7b9f4447e9fe17a4274c6fad67f (patch)
tree5f570d79dfc6eb4c736b708a99b3b2e5ed7608d1 /src/libnm-platform/nm-linux-platform.c
parente0a3970cd0ea64b36773deae96366bbe7d1efbee (diff)
parent7e9091a5960f67a84787c03153324915220e4816 (diff)
Update upstream source from tag 'upstream/1.54.0'
Update to upstream version '1.54.0'
with Debian dir efd253369d835d8f9c404eef4f97d88deb9625fe
Diffstat (limited to 'src/libnm-platform/nm-linux-platform.c')
-rw-r--r--src/libnm-platform/nm-linux-platform.c146
1 files changed, 117 insertions, 29 deletions
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index 24109568..d45893fe 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -41,6 +41,8 @@
 #include "libnm-platform/nm-netlink.h"
 #include "libnm-platform/nm-platform-utils.h"
 #include "libnm-platform/nmp-netns.h"
+#include "libnm-platform/nmp-ethtool.h"
+#include "libnm-platform/nmp-ethtool-ioctl.h"
 #include "libnm-platform/devlink/nm-devlink.h"
 #include "libnm-platform/wifi/nm-wifi-utils-wext.h"
 #include "libnm-platform/wifi/nm-wifi-utils.h"
@@ -1320,7 +1322,7 @@ _linktype_get_type(NMPlatform       *platform,
         NMPUtilsEthtoolDriverInfo driver_info;
 
         /* Fallback OVS detection for kernel <= 3.16 */
-        if (nmp_utils_ethtool_get_driver_info(ifindex, &driver_info)) {
+        if (nmp_ethtool_ioctl_get_driver_info(ifindex, &driver_info)) {
             if (nm_streq(driver_info.driver, "openvswitch"))
                 return NM_LINK_TYPE_OPENVSWITCH;
 
@@ -4037,14 +4039,15 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter
     NMPlatformIP4RtNextHop         *v4_nh_extra_nexthops      = v4_nh_extra_nexthops_stack;
     guint                           v4_nh_extra_alloc = G_N_ELEMENTS(v4_nh_extra_nexthops_stack);
     guint32                         mss;
-    guint32                         window   = 0;
-    guint32                         cwnd     = 0;
-    guint32                         initcwnd = 0;
-    guint32                         initrwnd = 0;
-    guint32                         mtu      = 0;
-    guint32                         rto_min  = 0;
-    guint32                         lock     = 0;
-    gboolean                        quickack = FALSE;
+    guint32                         window      = 0;
+    guint32                         cwnd        = 0;
+    guint32                         initcwnd    = 0;
+    guint32                         initrwnd    = 0;
+    guint32                         mtu         = 0;
+    guint32                         rto_min     = 0;
+    guint32                         lock        = 0;
+    gboolean                        quickack    = FALSE;
+    gboolean                        rto_min_set = FALSE;
 
     nm_assert((parse_nlmsg_iter->iter_more && parse_nlmsg_iter->ip6_route.next_multihop > 0)
               || (!parse_nlmsg_iter->iter_more && parse_nlmsg_iter->ip6_route.next_multihop == 0));
@@ -4290,8 +4293,10 @@ rta_multipath_done:
             initrwnd = nla_get_u32(mtb[RTAX_INITRWND]);
         if (mtb[RTAX_MTU])
             mtu = nla_get_u32(mtb[RTAX_MTU]);
-        if (mtb[RTAX_RTO_MIN])
-            rto_min = nla_get_u32(mtb[RTAX_RTO_MIN]);
+        if (mtb[RTAX_RTO_MIN] && NM_FLAGS_HAS(lock, 1U << RTAX_RTO_MIN)) {
+            rto_min     = nla_get_u32(mtb[RTAX_RTO_MIN]);
+            rto_min_set = TRUE;
+        }
         if (mtb[RTAX_QUICKACK])
             quickack = !!nla_get_u32(mtb[RTAX_QUICKACK]);
     }
@@ -4362,6 +4367,7 @@ rta_multipath_done:
     obj->ip_route.initcwnd      = initcwnd;
     obj->ip_route.initrwnd      = initrwnd;
     obj->ip_route.rto_min       = rto_min;
+    obj->ip_route.rto_min_set   = rto_min_set;
     obj->ip_route.quickack      = quickack;
     obj->ip_route.mtu           = mtu;
     obj->ip_route.lock_window   = NM_FLAGS_HAS(lock, 1 << RTAX_WINDOW);
@@ -5634,12 +5640,19 @@ nla_put_failure:
 static guint32
 ip_route_get_lock_flag(const NMPlatformIPRoute *route)
 {
-    return (((guint32) route->lock_window) << RTAX_WINDOW)
-           | (((guint32) route->lock_cwnd) << RTAX_CWND)
-           | (((guint32) route->lock_initcwnd) << RTAX_INITCWND)
-           | (((guint32) route->lock_initrwnd) << RTAX_INITRWND)
-           | (((guint32) route->lock_mtu) << RTAX_MTU)
-           | (((guint32) route->lock_mss) << RTAX_ADVMSS);
+    guint32 ret;
+
+    ret = (((guint32) route->lock_window) << RTAX_WINDOW)
+          | (((guint32) route->lock_cwnd) << RTAX_CWND)
+          | (((guint32) route->lock_initcwnd) << RTAX_INITCWND)
+          | (((guint32) route->lock_initrwnd) << RTAX_INITRWND)
+          | (((guint32) route->lock_mtu) << RTAX_MTU)
+          | (((guint32) route->lock_mss) << RTAX_ADVMSS);
+
+    /* the rto-min value is ignored by kernel unless the lock flag is set */
+    ret |= (((guint32) route->rto_min_set) << RTAX_RTO_MIN);
+
+    return ret;
 }
 
 static gboolean
@@ -5803,7 +5816,7 @@ _nl_msg_new_route(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPObject *ob
             NLA_PUT_U32(msg, RTAX_INITRWND, obj->ip_route.initrwnd);
         if (obj->ip_route.mtu)
             NLA_PUT_U32(msg, RTAX_MTU, obj->ip_route.mtu);
-        if (obj->ip_route.rto_min)
+        if (obj->ip_route.rto_min_set)
             NLA_PUT_U32(msg, RTAX_RTO_MIN, obj->ip_route.rto_min);
         if (obj->ip_route.quickack)
             NLA_PUT_U32(msg, RTAX_QUICKACK, obj->ip_route.quickack);
@@ -6130,7 +6143,7 @@ nla_put_failure:
         const int         _dirfd  = (dirfd);                                                      \
         const char *const _path   = (path);                                                       \
                                                                                                   \
-        nm_assert(_path &&_path[0]);                                                              \
+        nm_assert(_path && _path[0]);                                                             \
         g_assert(!strstr(_path, "/../"));                                                         \
         if (_dirfd < 0) {                                                                         \
             nm_assert(!_pathid);                                                                  \
@@ -6138,7 +6151,7 @@ nla_put_failure:
             nm_assert(NM_STR_HAS_PREFIX(_path, "/proc/sys/") || NM_STR_HAS_PREFIX(_path, "/sys/") \
                       || NM_STR_HAS_PREFIX(_path, "/proc/net"));                                  \
         } else {                                                                                  \
-            nm_assert(_pathid &&_pathid[0] && _pathid[0] != '/');                                 \
+            nm_assert(_pathid && _pathid[0] && _pathid[0] != '/');                                \
             nm_assert(_path[0] != '/');                                                           \
         }                                                                                         \
     }                                                                                             \
@@ -7562,7 +7575,7 @@ cache_on_change(NMPlatform      *platform,
                              NM_LINK_TYPE_IP6GRETAP,
                              NM_LINK_TYPE_INFINIBAND,
                              NM_LINK_TYPE_MACVLAN,
-                             NM_LINK_TYPE_MACVLAN,
+                             NM_LINK_TYPE_MACVTAP,
                              NM_LINK_TYPE_SIT,
                              NM_LINK_TYPE_TUN,
                              NM_LINK_TYPE_VLAN,
@@ -8955,8 +8968,8 @@ link_supports_carrier_detect(NMPlatform *platform, int ifindex)
      * us whether the device actually supports carrier detection in the first
      * place. We assume any device that does implements one of these two APIs.
      */
-    return nmp_utils_ethtool_supports_carrier_detect(ifindex)
-           || nmp_utils_mii_supports_carrier_detect(ifindex);
+    return nmp_ethtool_ioctl_supports_carrier_detect(ifindex)
+           || nmp_mii_ioctl_supports_carrier_detect(ifindex);
 }
 
 static gboolean
@@ -8974,7 +8987,7 @@ link_supports_vlans(NMPlatform *platform, int ifindex)
     if (!nm_platform_netns_push(platform, &netns))
         return FALSE;
 
-    return nmp_utils_ethtool_supports_vlans(ifindex);
+    return nmp_ethtool_ioctl_supports_vlans(ifindex);
 }
 
 static gboolean
@@ -9052,7 +9065,7 @@ link_get_permanent_address_ethtool(NMPlatform *platform, int ifindex, NMPLinkAdd
     if (!nm_platform_netns_push(platform, &netns))
         return FALSE;
 
-    if (!nmp_utils_ethtool_get_permanent_address(ifindex, buffer, &len))
+    if (!nmp_ethtool_ioctl_get_permanent_address(ifindex, buffer, &len))
         return FALSE;
     nm_assert(len <= _NM_UTILS_HWADDR_LEN_MAX);
     memcpy(out_address->data, buffer, len);
@@ -9195,7 +9208,7 @@ sriov_async_finish_err(SriovAsyncState *async_state, GError *error)
     g_object_unref(async_state->platform);
     g_object_unref(async_state->cancellable);
     g_free(async_state);
-    g_free(error);
+    nm_g_error_free(error);
 }
 
 static void
@@ -10380,7 +10393,7 @@ link_get_wake_on_lan(NMPlatform *platform, int ifindex)
         return FALSE;
 
     if (type == NM_LINK_TYPE_ETHERNET)
-        return nmp_utils_ethtool_get_wake_on_lan(ifindex);
+        return nmp_ethtool_ioctl_get_wake_on_lan(ifindex);
     else if (type == NM_LINK_TYPE_WIFI) {
         WIFI_GET_WIFI_DATA(wifi_data, platform, ifindex, FALSE);
 
@@ -10405,7 +10418,7 @@ link_get_driver_info(NMPlatform *platform,
     if (!nm_platform_netns_push(platform, &netns))
         return FALSE;
 
-    if (!nmp_utils_ethtool_get_driver_info(ifindex, &driver_info))
+    if (!nmp_ethtool_ioctl_get_driver_info(ifindex, &driver_info))
         return FALSE;
     NM_SET_OUT(out_driver_name, g_strdup(driver_info.driver));
     NM_SET_OUT(out_driver_version, g_strdup(driver_info.version));
@@ -10465,7 +10478,7 @@ parse_fdb_cb(const struct nl_msg *msg, void *arg)
 }
 
 NMEtherAddr **
-nm_linux_platform_get_link_fdb_table(NMPlatform *platform, int *ifindexes, guint ifindexes_len)
+nm_linux_platform_get_bridge_fdb(NMPlatform *platform, int *ifindexes, guint ifindexes_len)
 {
     int                            nle;
     struct nl_sock                *sk        = NULL;
@@ -11820,6 +11833,74 @@ mptcp_addrs_dump(NMPlatform *platform)
 
 /*****************************************************************************/
 
+static gboolean
+ethtool_get_pause(NMPlatform *platform, int ifindex, NMEthtoolPauseState *pause)
+{
+    NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
+
+    return nmp_ethtool_get_pause(priv->sk_genl_sync,
+                                 genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
+                                 ifindex,
+                                 pause);
+}
+
+static gboolean
+ethtool_set_pause(NMPlatform *platform, int ifindex, const NMEthtoolPauseState *pause)
+{
+    NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
+
+    return nmp_ethtool_set_pause(priv->sk_genl_sync,
+                                 genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
+                                 ifindex,
+                                 pause);
+}
+
+static gboolean
+ethtool_get_eee(NMPlatform *platform, int ifindex, NMEthtoolEEEState *eee)
+{
+    NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
+
+    return nmp_ethtool_get_eee(priv->sk_genl_sync,
+                               genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
+                               ifindex,
+                               eee);
+}
+
+static gboolean
+ethtool_set_eee(NMPlatform *platform, int ifindex, const NMEthtoolEEEState *eee)
+{
+    NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
+
+    return nmp_ethtool_set_eee(priv->sk_genl_sync,
+                               genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
+                               ifindex,
+                               eee);
+}
+
+static gboolean
+ethtool_get_ring(NMPlatform *platform, int ifindex, NMEthtoolRingState *ring)
+{
+    NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
+
+    return nmp_ethtool_get_ring(priv->sk_genl_sync,
+                                genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
+                                ifindex,
+                                ring);
+}
+
+static gboolean
+ethtool_set_ring(NMPlatform *platform, int ifindex, const NMEthtoolRingState *ring)
+{
+    NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
+
+    return nmp_ethtool_set_ring(priv->sk_genl_sync,
+                                genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
+                                ifindex,
+                                ring);
+}
+
+/*****************************************************************************/
+
 static void
 cache_update_link_udev(NMPlatform *platform, int ifindex, struct udev_device *udevice)
 {
@@ -12317,4 +12398,11 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
     platform_class->genl_get_family_id = genl_get_family_id;
     platform_class->mptcp_addr_update  = mptcp_addr_update;
     platform_class->mptcp_addrs_dump   = mptcp_addrs_dump;
+
+    platform_class->ethtool_set_pause = ethtool_set_pause;
+    platform_class->ethtool_get_pause = ethtool_get_pause;
+    platform_class->ethtool_set_eee   = ethtool_set_eee;
+    platform_class->ethtool_get_eee   = ethtool_get_eee;
+    platform_class->ethtool_set_ring  = ethtool_set_ring;
+    platform_class->ethtool_get_ring  = ethtool_get_ring;
 }