diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index 0915e9156..673d23619 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -137,13 +137,13 @@ _set_bond_attr(NMDevice *device, const char *attr, const char *value) return ret; } -#define _set_bond_attr_take(device, attr, value) \ - G_STMT_START \ - { \ - gs_free char *_tmp = (value); \ - \ - _set_bond_attr(device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, _tmp); \ - } \ +#define _set_bond_attr_take(device, attr, value) \ + G_STMT_START \ + { \ + gs_free char *_tmp = (value); \ + \ + _set_bond_attr(device, attr, _tmp); \ + } \ G_STMT_END #define _set_bond_attr_printf(device, attr, fmt, ...) \ diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 4034fdaad..2059ce427 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -14,7 +14,6 @@ #include #include -#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h" #include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" @@ -1894,7 +1893,7 @@ get_ip_method_auto(NMDevice *device, int addr_family) /* We cannot do DHCPv4 on a PPP link, instead we get "auto" IP addresses * by pppd. Return "manual" here, which has the suitable effect to a * (zero) manual addresses in addition. */ - return NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + return NM_SETTING_IP4_CONFIG_METHOD_MANUAL; } return NM_SETTING_IP6_CONFIG_METHOD_AUTO; diff --git a/src/core/devices/nm-device-hsr.c b/src/core/devices/nm-device-hsr.c index 8156fa779..59454ee34 100644 --- a/src/core/devices/nm-device-hsr.c +++ b/src/core/devices/nm-device-hsr.c @@ -94,8 +94,10 @@ update_properties(NMDevice *device) CHECK_PROPERTY_CHANGED(multicast_spec, PROP_MULTICAST_SPEC); CHECK_PROPERTY_CHANGED(prp, PROP_PRP); - if (!nm_ether_addr_equal(&priv->props.supervision_address, &props->supervision_address)) + if (!nm_ether_addr_equal(&priv->props.supervision_address, &props->supervision_address)) { + priv->props.supervision_address = props->supervision_address; _notify(self, PROP_SUPERVISION_ADDRESS); + } g_object_thaw_notify((GObject *) device); } diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c index faab86d0a..b277c378a 100644 --- a/src/core/devices/nm-device-tun.c +++ b/src/core/devices/nm-device-tun.c @@ -242,12 +242,14 @@ create_and_realize(NMDevice *device, g_return_val_if_reached(FALSE); } - owner = _nm_utils_ascii_str_to_int64(nm_setting_tun_get_owner(s_tun), 10, 0, G_MAXINT32, -1); + owner = + _nm_utils_ascii_str_to_int64(nm_setting_tun_get_owner(s_tun), 10, 0, G_MAXUINT32 - 1, -1); if (owner != -1) { props.owner_valid = TRUE; props.owner = owner; } - group = _nm_utils_ascii_str_to_int64(nm_setting_tun_get_group(s_tun), 10, 0, G_MAXINT32, -1); + group = + _nm_utils_ascii_str_to_int64(nm_setting_tun_get_group(s_tun), 10, 0, G_MAXUINT32 - 1, -1); if (group != -1) { props.group_valid = TRUE; props.group = group; @@ -278,7 +280,7 @@ _same_og(const char *str, gboolean og_valid, guint32 og_num) { gint64 v; - v = _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXINT32, -1); + v = _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXUINT32 - 1, -1); return (!og_valid && (v == (gint64) -1)) || (og_valid && (((guint32) v) == og_num)); } diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index 7dfd6504a..6d272a95c 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -235,7 +235,7 @@ attach_port(NMDevice *device, _LOGI(LOGD_DEVICE, "attached VRF port %s", port_iface); } else - _LOGI(LOGD_BOND, "VRF port %s was attached", port_iface); + _LOGI(LOGD_DEVICE, "VRF port %s was attached", port_iface); return TRUE; } diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c index e08b379ad..5c90911fc 100644 --- a/src/core/devices/nm-lldp-listener.c +++ b/src/core/devices/nm-lldp-listener.c @@ -310,7 +310,7 @@ format_string(const guint8 *data, gsize len, gboolean allow_trim, char **out_to_ if (len == 0) return NULL; - if (memchr(data, len, '\0')) + if (memchr(data, '\0', len)) return NULL; return nm_utils_buf_utf8safe_escape(data, diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 74fcd80bc..164bfd356 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -2249,7 +2249,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) ovs_bridge->connection_uuid, ""), (strtmp1 = _strdict_to_string(ovs_bridge->external_ids)), - (strtmp2 = _strdict_to_string(ovs_bridge->external_ids))); + (strtmp2 = _strdict_to_string(ovs_bridge->other_config))); } } else { gs_free char *strtmp1 = NULL; diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index ce03c6077..30cfd8e68 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -68,7 +68,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = { REQ(NM_DHCP_OPTION_DHCP4_ARP_CACHE_TIMEOUT, "arp_cache_timeout", FALSE), REQ(NM_DHCP_OPTION_DHCP4_IEEE802_3_ENCAPSULATION, "ieee802_3_encapsulation", FALSE), REQ(NM_DHCP_OPTION_DHCP4_DEFAULT_TCP_TTL, "default_tcp_ttl", FALSE), - REQ(NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_INTERVAL, "tcp_keepalive_internal", FALSE), + REQ(NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_INTERVAL, "tcp_keepalive_interval", FALSE), REQ(NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_GARBAGE, "tcp_keepalive_garbage", FALSE), REQ(NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC, "vendor_encapsulated_options", FALSE), REQ(NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, "netbios_name_servers", FALSE), diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 15293fa38..949d87207 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -1224,7 +1224,7 @@ lease_option_print_domain_name(const uint8_t *cache, } case 0xC0: /* back pointer */ { - size_t offset = (c & 0x3F) << 16; + size_t offset = (c & 0x3F) << 8; /* * The offset is given as two bytes (in big endian), where the diff --git a/src/core/dhcp/tests/test-dhcp-utils.c b/src/core/dhcp/tests/test-dhcp-utils.c index b81523e19..de1be6538 100644 --- a/src/core/dhcp/tests/test-dhcp-utils.c +++ b/src/core/dhcp/tests/test-dhcp-utils.c @@ -239,6 +239,76 @@ test_parse_search_list(void) g_assert_cmpint(g_strv_length(domains), ==, 1); g_assert_cmpstr(domains[0], ==, "okay"); g_strfreev(domains); + + /* Test that the message compression works when the offset uses both bytes */ + data = (guint8[]) { + /* clang-format off */ + /* offset 0 */ + 0x3e, + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 0x00, + /* offset 0x40 */ + 0x3e, + 'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b', + 'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b', + 'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b', + 'b','b','b','b','b','b','b','b','b','b','b','b','b','b', + 0x00, + /* offset 0x80 */ + 0x3e, + 'c','c','c','c','c','c','c','c','c','c','c','c','c','c','c','c', + 'c','c','c','c','c','c','c','c','c','c','c','c','c','c','c','c', + 'c','c','c','c','c','c','c','c','c','c','c','c','c','c','c','c', + 'c','c','c','c','c','c','c','c','c','c','c','c','c','c', + 0x00, + /* offset 0xc0 */ + 0x3e, + 'd','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d', + 'd','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d', + 'd','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d', + 'd','d','d','d','d','d','d','d','d','d','d','d','d','d', + 0x00, + /* offset 0x100 */ + 0x3e, + 'e','e','e','e','e','e','e','e','e','e','e','e','e','e','e','e', + 'e','e','e','e','e','e','e','e','e','e','e','e','e','e','e','e', + 'e','e','e','e','e','e','e','e','e','e','e','e','e','e','e','e', + 'e','e','e','e','e','e','e','e','e','e','e','e','e','e', + 0x00, + /* offset 0x140 */ + 0x06, 'f','o','o','b','a','r', 0x03, 'c', 'o', 'm', 0x00, + 0x04, 't', 'e', 's', 't', 0xc1, 0x40, /* back pointer to offset 0x140*/ + /* clang-format on */ + }; + + domains = nm_dhcp_lease_data_parse_search_list(data, + 0x153, + "eth0", + AF_INET, + NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 7); + g_assert_cmpstr(domains[0], + ==, + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + g_assert_cmpstr(domains[1], + ==, + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); + g_assert_cmpstr(domains[2], + ==, + "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"); + g_assert_cmpstr(domains[3], + ==, + "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"); + g_assert_cmpstr(domains[4], + ==, + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); + g_assert_cmpstr(domains[5], ==, "foobar.com"); + g_assert_cmpstr(domains[6], ==, "test.foobar.com"); + g_strfreev(domains); } static void diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c index 3083de009..1a2bf4807 100644 --- a/src/core/ndisc/nm-ndisc.c +++ b/src/core/ndisc/nm-ndisc.c @@ -1490,7 +1490,7 @@ clean_addresses(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint g_array_set_size(rdata->addresses, j); } - if (_array_set_size_max(rdata->gateways, priv->config.max_addresses)) + if (_array_set_size_max(rdata->addresses, priv->config.max_addresses)) *changed |= NM_NDISC_CONFIG_ADDRESSES; } diff --git a/src/core/nm-bond-manager.c b/src/core/nm-bond-manager.c index 116cb7374..abaab7d4f 100644 --- a/src/core/nm-bond-manager.c +++ b/src/core/nm-bond-manager.c @@ -916,21 +916,21 @@ nm_bond_manager_send_arp(int bond_ifindex, if (announce_fdb) { /* if we are announcing the FDB we do a RARP, we don't set the * source/dest IPv4 address */ - int ifindexes[] = {bridge_ifindex, bond_ifindex}; - int i; - gs_free NMEtherAddr **fdb_addrs = NULL; + int ifindexes[] = {bridge_ifindex, bond_ifindex}; + int i; + nm_auto_freev NMEtherAddr **fdb_addrs = NULL; - fdb_addrs = nm_linux_platform_get_link_fdb_table(platform, ifindexes, 2); + fdb_addrs = nm_linux_platform_get_bridge_fdb(platform, ifindexes, 2); /* we want to send a Reverse ARP (RARP) packet */ data.op = htons(ARP_OP_RARP); i = 0; while (fdb_addrs[i] != NULL) { NMEtherAddr *tmp_hwaddr = fdb_addrs[i]; + memcpy(data.s_hw_addr, tmp_hwaddr, ETH_ALEN); memcpy(data.d_hw_addr, tmp_hwaddr, ETH_ALEN); memcpy(data.s_addr, tmp_hwaddr, ETH_ALEN); - g_free(tmp_hwaddr); if (sendto(sockfd, &data, sizeof(data), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) return FALSE; i++; diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 895a99177..d3c2eb21c 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -4642,13 +4642,13 @@ get_max_rate_vht_80_ss3(int mcs) case 5: return 702000000; case 6: - return 0; + return 0; /* invalid */ case 7: return 877500000; case 8: - return 105300000; + return 1053000000; case 9: - return 117000000; + return 1170000000; } return 0; } @@ -4732,7 +4732,7 @@ get_max_rate_vht_160_ss3(int mcs) case 8: return 2106000000; case 9: - return 0; + return 0; /* invalid */ } return 0; } @@ -5417,7 +5417,7 @@ again: if ((g = g_atomic_int_get(&g_static)) == -1) { gid_t g2; - g2 = geteuid(); + g2 = getegid(); g = g2; nm_assert(g == g2); nm_assert(g >= 0); diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index 4a08d565a..54d9dd7fb 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -2725,6 +2725,66 @@ test_link_set_properties(void) /*****************************************************************************/ +static void +test_link_get_bridge_fdb(void) +{ + const NMPlatformLink *link; + nm_auto_freev NMEtherAddr **addrs; + int ifindex[2]; + guint8 expected[][6] = { + {0x00, 0x99, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x99, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x99, 0x00, 0x00, 0x00, 0x03}, + {0x00, 0x99, 0x00, 0x00, 0x00, 0x05}, + }; + guint i; + guint j; + + ifindex[0] = + nmtstp_link_bridge_add(NULL, -1, "br-test-1", &nm_platform_lnk_bridge_default)->ifindex; + ifindex[1] = + nmtstp_link_bridge_add(NULL, -1, "br-test-2", &nm_platform_lnk_bridge_default)->ifindex; + + link = nmtstp_link_get(NULL, ifindex[0], "br-test-1"); + g_assert(link); + link = nmtstp_link_get(NULL, ifindex[1], "br-test-2"); + g_assert(link); + + nmtstp_run_command_check("bridge fdb add dev br-test-1 00:99:00:00:00:01"); + nmtstp_run_command_check("bridge fdb add dev br-test-1 00:99:00:00:00:02"); + nmtstp_run_command_check("bridge fdb add dev br-test-1 00:99:00:00:00:03"); + nmtstp_run_command_check("bridge fdb add dev br-test-2 00:99:00:00:00:01"); + nmtstp_run_command_check("bridge fdb add dev br-test-2 00:99:00:00:00:05"); + + addrs = nm_linux_platform_get_bridge_fdb(NM_PLATFORM_GET, ifindex, 2); + g_assert(addrs); + + /* Check for expected entries */ + for (i = 0; i < G_N_ELEMENTS(expected); i++) { + gboolean found = FALSE; + + for (j = 0; addrs[j]; j++) { + if (memcmp(addrs[j], expected[i], ETH_ALEN) == 0) { + found = TRUE; + break; + } + } + g_assert(found); + } + + /* No dupes */ + for (i = 0; addrs[i]; i++) { + for (j = i + 1; addrs[j]; j++) { + g_assert_cmpint(memcmp(addrs[i], addrs[j], ETH_ALEN), !=, 0); + } + } + + nmtstp_link_delete(NULL, -1, ifindex[0], "br-test-1", TRUE); + nmtstp_link_delete(NULL, -1, ifindex[1], "br-test-2", TRUE); +} + +/*****************************************************************************/ + static void test_create_many_links_do(guint n_devices) { @@ -4106,6 +4166,8 @@ _nmtstp_setup_tests(void) test_software_detect_add("/link/software/detect/wireguard/1", NM_LINK_TYPE_WIREGUARD, 1); test_software_detect_add("/link/software/detect/wireguard/2", NM_LINK_TYPE_WIREGUARD, 2); + g_test_add_func("/link/get-bridge-fdb", test_link_get_bridge_fdb); + g_test_add_func("/link/software/vlan/set-xgress", test_vlan_set_xgress); g_test_add_func("/link/set-properties", test_link_set_properties); diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index d5f56dcde..514b7c0d3 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -3082,7 +3082,7 @@ _signal_handle(NMSupplicantInterface *self, const char *status; const char *parameter; - if (g_variant_is_of_type(parameters, G_VARIANT_TYPE("(ss)"))) + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(ss)"))) return; g_variant_get(parameters, "(&s&s)", &status, ¶meter); diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c index 24e5807ac..b70247c1c 100644 --- a/src/libnm-core-impl/nm-setting-infiniband.c +++ b/src/libnm-core-impl/nm-setting-infiniband.c @@ -212,6 +212,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR_INVALID_PROPERTY, _("Must specify a P_Key if specifying parent")); g_prefix_error(error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + return FALSE; } } diff --git a/src/libnm-core-impl/nm-setting-ipvlan.c b/src/libnm-core-impl/nm-setting-ipvlan.c index fafa37b6e..0468e31fd 100644 --- a/src/libnm-core-impl/nm-setting-ipvlan.c +++ b/src/libnm-core-impl/nm-setting-ipvlan.c @@ -156,6 +156,19 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } } + if (!NM_IN_SET(priv->mode, + NM_SETTING_IPVLAN_MODE_L2, + NM_SETTING_IPVLAN_MODE_L3, + NM_SETTING_IPVLAN_MODE_L3S)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("unsupported mode %u"), + priv->mode); + g_prefix_error(error, "%s.%s: ", NM_SETTING_IPVLAN_SETTING_NAME, NM_SETTING_IPVLAN_MODE); + return FALSE; + } + if (priv->private_flag && priv->vepa) { g_set_error(error, NM_CONNECTION_ERROR, diff --git a/src/libnm-core-impl/nm-setting-match.c b/src/libnm-core-impl/nm-setting-match.c index 255283fc5..dc743b159 100644 --- a/src/libnm-core-impl/nm-setting-match.c +++ b/src/libnm-core-impl/nm-setting-match.c @@ -309,9 +309,10 @@ nm_setting_match_clear_kernel_command_lines(NMSettingMatch *setting) * @setting: the #NMSettingMatch * @length: (out) (optional): the length of the returned interface names array. * - * Returns all the interface names. + * Returns all the kernel command line arguments. * - * Returns: (transfer none) (array length=length): the configured interface names. + * Returns: (transfer none) (array length=length): the configured kernel command + * line arguments. * * Since: 1.26 **/ @@ -344,7 +345,7 @@ nm_setting_match_get_num_drivers(NMSettingMatch *setting) /** * nm_setting_match_get_driver: * @setting: the #NMSettingMatch - * @idx: index number of the DNS search domain to return + * @idx: index number of the driver to return * * Since 1.46, access at index "len" is allowed and returns NULL. * @@ -443,7 +444,7 @@ nm_setting_match_clear_drivers(NMSettingMatch *setting) /** * nm_setting_match_get_drivers: * @setting: the #NMSettingMatch - * @length: (out) (optional): the length of the returned interface names array. + * @length: (out) (optional): the length of the returned drivers array. * * Returns all the drivers. * diff --git a/src/libnm-core-impl/nm-setting-tun.c b/src/libnm-core-impl/nm-setting-tun.c index 05460104a..cac0f10be 100644 --- a/src/libnm-core-impl/nm-setting-tun.c +++ b/src/libnm-core-impl/nm-setting-tun.c @@ -166,7 +166,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } if (priv->owner) { - if (_nm_utils_ascii_str_to_int64(priv->owner, 10, 0, G_MAXINT32, -1) == -1) { + if (_nm_utils_ascii_str_to_int64(priv->owner, 10, 0, G_MAXUINT32 - 1, -1) == -1) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -178,7 +178,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } if (priv->group) { - if (_nm_utils_ascii_str_to_int64(priv->group, 10, 0, G_MAXINT32, -1) == -1) { + if (_nm_utils_ascii_str_to_int64(priv->group, 10, 0, G_MAXUINT32 - 1, -1) == -1) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 2cc50f8f7..f796e53df 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -10519,7 +10519,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; diff --git a/src/libnm-platform/nm-linux-platform.h b/src/libnm-platform/nm-linux-platform.h index 3f591b7f1..c7f1b17a2 100644 --- a/src/libnm-platform/nm-linux-platform.h +++ b/src/libnm-platform/nm-linux-platform.h @@ -26,7 +26,7 @@ GType nm_linux_platform_get_type(void); struct _NMDedupMultiIndex; 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); NMPlatform *nm_linux_platform_new(struct _NMDedupMultiIndex *multi_idx, gboolean log_with_ptr, diff --git a/src/libnm-platform/nmp-ethtool.c b/src/libnm-platform/nmp-ethtool.c index ed028f6a1..28d12ffb1 100644 --- a/src/libnm-platform/nmp-ethtool.c +++ b/src/libnm-platform/nmp-ethtool.c @@ -153,7 +153,7 @@ ethtool_send_and_recv(struct nl_sock *sock, out: if (nle < 0 && err_msg && *err_msg == NULL) - *err_msg = strdup(nm_strerror(nle)); + *err_msg = g_strdup(nm_strerror(nle)); if (nle >= 0 && cb_result < 0) nle = cb_result; diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index e11bfb3f5..56533c99c 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -893,7 +893,7 @@ const NMPObject * nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in6_addr *address) { _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_IP6_ADDRESS); - obj->ip4_address.ifindex = ifindex; + obj->ip6_address.ifindex = ifindex; if (address) obj->ip6_address.address = *address; return obj; diff --git a/src/nm-initrd-generator/nmi-cmdline-reader.c b/src/nm-initrd-generator/nmi-cmdline-reader.c index ba5380afb..89deddf0a 100644 --- a/src/nm-initrd-generator/nmi-cmdline-reader.c +++ b/src/nm-initrd-generator/nmi-cmdline-reader.c @@ -1063,27 +1063,44 @@ reader_parse_vlan(Reader *reader, char *argument) const char *vlan; const char *phy; const char *vlanid; + guint64 id; vlan = get_word(&argument, ':'); phy = get_word(&argument, ':'); + if (!vlan) { + _LOGW(LOGD_CORE, "missing VLAN interface name"); + return; + } + + if (!phy) { + _LOGW(LOGD_CORE, "missing VLAN parent"); + return; + } + for (vlanid = vlan + strlen(vlan); vlanid > vlan; vlanid--) { if (!g_ascii_isdigit(*(vlanid - 1))) break; } + if (vlanid[0] == '\0') { + _LOGW(LOGD_CORE, "missing VLAN id in '%s'", vlan); + return; + } + + id = _nm_utils_ascii_str_to_int64(vlanid, 10, 0, 4094, G_MAXUINT); + if (id == G_MAXUINT) { + _LOGW(LOGD_CORE, "invalid VLAN id '%s'", vlanid); + return; + } + connection = reader_get_connection(reader, vlan, NM_SETTING_VLAN_SETTING_NAME, TRUE); s_vlan = nm_connection_get_setting_vlan(connection); - g_object_set(s_vlan, - NM_SETTING_VLAN_PARENT, - phy, - NM_SETTING_VLAN_ID, - (guint) _nm_utils_ascii_str_to_int64(vlanid, 10, 0, G_MAXUINT, G_MAXUINT), - NULL); + g_object_set(s_vlan, NM_SETTING_VLAN_PARENT, phy, NM_SETTING_VLAN_ID, (guint32) id, NULL); if (argument && *argument) - _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); + _LOGW(LOGD_CORE, "ignoring extra VLAN argument '%s'", argument); if (!nm_strv_ptrarray_contains(reader->vlan_parents, phy)) g_ptr_array_add(reader->vlan_parents, g_strdup(phy)); diff --git a/src/nm-initrd-generator/tests/test-cmdline-reader.c b/src/nm-initrd-generator/tests/test-cmdline-reader.c index cd7b1069b..413f61c65 100644 --- a/src/nm-initrd-generator/tests/test-cmdline-reader.c +++ b/src/nm-initrd-generator/tests/test-cmdline-reader.c @@ -1846,6 +1846,66 @@ test_vlan_over_bond(void) } } +static void +test_vlan_invalid(void) +{ + { + /* Case 1: Missing name */ + const char *const *ARGV0 = NM_MAKE_STRV("vlan="); + gs_unref_hashtable GHashTable *connections = NULL; + + NMTST_EXPECT_NM_WARN("cmdline-reader: missing VLAN interface name"); + connections = _parse_cons(ARGV0); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_test_assert_expected_messages(); + } + + { + /* Case 2: Missing parent */ + const char *const *ARGV0 = NM_MAKE_STRV("vlan=vlan12"); + gs_unref_hashtable GHashTable *connections = NULL; + + NMTST_EXPECT_NM_WARN("cmdline-reader: missing VLAN parent"); + connections = _parse_cons(ARGV0); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_test_assert_expected_messages(); + } + + { + /* Case 3: Interface name without trailing digits should fail, + * not trigger a GLib assertion. */ + const char *const *ARGV0 = NM_MAKE_STRV("vlan=myvlan:eth0"); + gs_unref_hashtable GHashTable *connections = NULL; + + NMTST_EXPECT_NM_WARN("cmdline-reader: missing VLAN id in 'myvlan'"); + connections = _parse_cons(ARGV0); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_test_assert_expected_messages(); + } + + { + /* Case 4: An invalid VLAN id should be rejected */ + const char *const *ARGV0 = NM_MAKE_STRV("vlan=myvlan4095:eth0"); + gs_unref_hashtable GHashTable *connections = NULL; + + NMTST_EXPECT_NM_WARN("cmdline-reader: invalid VLAN id '4095'"); + connections = _parse_cons(ARGV0); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_test_assert_expected_messages(); + } + + { + /* Case 5: Extra arguments */ + const char *const *ARGV0 = NM_MAKE_STRV("vlan=eth0.80:eth0:reorder_hdr=on"); + gs_unref_hashtable GHashTable *connections = NULL; + + NMTST_EXPECT_NM_WARN("cmdline-reader: ignoring extra VLAN argument 'reorder_hdr=on'"); + connections = _parse_cons(ARGV0); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + g_test_assert_expected_messages(); + } +} + static void test_ibft_ip_dev(void) { @@ -2820,6 +2880,7 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/vlan", test_vlan); g_test_add_func("/initrd/cmdline/vlan/dhcp-on-parent", test_vlan_with_dhcp_on_parent); g_test_add_func("/initrd/cmdline/vlan/over-bond", test_vlan_over_bond); + g_test_add_func("/initrd/cmdline/vlan/invalid", test_vlan_invalid); g_test_add_func("/initrd/cmdline/bridge", test_bridge); g_test_add_func("/initrd/cmdline/bridge/default", test_bridge_default); g_test_add_func("/initrd/cmdline/bridge/ip", test_bridge_ip);