summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* nm-setting-bridge: add 'multicast-querier' bridge optionac/bridge_optionsAntonio Cardace2020-04-068-0/+68
| | | | https://bugzilla.redhat.com/show_bug.cgi?id=1755768
* nm-setting-bridge: add 'multicast-query-use-ifaddr' bridge optionAntonio Cardace2020-04-068-98/+166
| | | | https://bugzilla.redhat.com/show_bug.cgi?id=1755768
* nm-setting-bridge: add 'multicast-router' bridge optionAntonio Cardace2020-04-069-0/+155
| | | | | | Also add related unit test. https://bugzilla.redhat.com/show_bug.cgi?id=1755768
* nm-setting-bridge: add 'vlan-stats-enabled' bridge optionAntonio Cardace2020-04-068-14/+80
| | | | https://bugzilla.redhat.com/show_bug.cgi?id=1755768
* nm-setting-bridge: add 'vlan-protocol' bridge optionAntonio Cardace2020-04-069-0/+125
| | | | | | Also add related unit test. https://bugzilla.redhat.com/show_bug.cgi?id=1755768
* nm-setting-bridge: add 'group-address' bridge optionAntonio Cardace2020-04-0612-65/+382
| | | | | | Also add related unit test. https://bugzilla.redhat.com/show_bug.cgi?id=1755768
* nm-setting-bridge: hide GObject structs from public API and embed private dataAntonio Cardace2020-04-062-18/+16
| | | | | | | | | | Hide the object and class structures from public API. This is an API and ABI break, but of something that is very likely unused. This is mainly done to embed the private structure in the object itself. This has benefits for performance and debugability.
* libnm,cli: merge branch 'th/libnm-setting-vpn-cleanup'Thomas Haller2020-04-049-343/+1118
|\ | | | | | | | | | | https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/390 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/453
| * release: update NEWSThomas Haller2020-04-041-0/+4
| |
| * cli: support backslash escaping for cli options like vpn.data, vpn.secrets, ↵Thomas Haller2020-04-041-59/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | bond.options, ethernet.s390-options This is obviously a change in behavior, as we now honor backslash escape sequences. With this change, all string values can be expressed, both as option keys and values. Previously, you could for example not set vpn.secrets to have a ',' and you could not set vpn.data to nmcli connection modify "$PROFILE" +vpn.data 'ipsec-ike = aes256-sha2_256-modp2048,aes256-sha2_256-modp1536' Use a relatively simple backslash escaping scheme. The main goal of the scheme is that it doesn't change behavior for the majority of cases. It only changes behavior for setting an option if: - the string contains a backslash - and if the backslash proceeds one of the few characters that support escaping now (white space, ',', '\\', and '='). The only downside here is that backslash is only treated special, if it preceeds a character that requires escaping. That makes the behavior non intuitive. However, it allows to write most backslashes without escaping them as "\\\\" and thus keep previous behavior. The nmcli getters now also escape the options accordingly. That means, the string printed by the getter is also a valid input for the setter. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/390
| * cli: simplify _value_strsplit() by using nm_utils_strsplit_set_full()Thomas Haller2020-04-041-29/+8
| | | | | | | | | | | | | | | | | | | | | | The two modes VALUE_STRSPLIT_MODE_OBJLIST and VALUE_STRSPLIT_MODE_MULTILIST basically do regular split and afterwards g_strstrip() all values and remove empty tokens. That is what the NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP flag already does. Use it. There should be no change in behavior.
| * cli: allow setting VPN data and secrets to empty valuesThomas Haller2020-04-041-2/+0
| |
| * shared: add nm_utils_escaped_tokens_options_*() APIThomas Haller2020-04-043-0/+454
| | | | | | | | | | This will be used for splitting and escaping option parameters in nmcli (vpn.data).
| * shared: add flags for nm_utils_escaped_tokens_escape_full()Thomas Haller2020-04-042-27/+163
| | | | | | | | | | | | | | | | Add flags to explicitly escape leading or trailing spaces. Note that we were already escaping trailing spaces. This will be used later when supporting backslash escapes for option parameters for nmcli (vpn.data).
| * shared: refactor initializing character lookup tables for strsplitThomas Haller2020-04-041-8/+21
| |
| * shared/trivial: improve code comments about NMUtilsStrsplitSetFlags flagsThomas Haller2020-04-042-13/+21
| |
| * shared: add nm_str_is_stripped() utilThomas Haller2020-04-041-0/+11
| |
| * shared/tests: add nmtst_get_rand_word_length()Thomas Haller2020-04-041-0/+63
| | | | | | | | | | Will be used to get a random number with a certain distribution, that suitable to generate input values.
| * libnm: convert vpn-secrets to D-Bus in stable orderThomas Haller2020-04-041-16/+17
| | | | | | | | | | | | | | | | We should generate the GVariant in a stable manner. That implies to sort the keys first. Also, don't use the NM_SETTING_VPN_SECRETS getter, which first needs to clone all secrets.
| * libnm: avoid cloning secrets during vpn_secrets_from_dbus()Thomas Haller2020-04-041-4/+19
| | | | | | | | | | | | | | | | When we use _nm_utils_strdict_from_dbus(), we clone the secrets, but don't use nm_free_secret() for freeing them. And in fact, we clone the setings twice. It't really not too nice. Implement this without the property setter.
| * libnm: refactor property setters of data and secrets in NMSettingVpnThomas Haller2020-04-041-28/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Don't use _nm_utils_copy_strdict(). On a minor note, that function will always allocate a GHashTable, even if it only contains "" as only key. Later we would throw that out again, so it was unnecessary. Worse, using _nm_utils_copy_strdict() does not use nm_free_secrets as destroy function. While it's in general difficult to clear all places in memory where we copy the secrets around, we can easily avoid that. Also skip over %NULL keys and values. It probably would be a bug passing such arguments to the property. Better ignore them and not crash.
| * libnm: allow setting empty vpn.secrets itemThomas Haller2020-04-042-24/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Like for data, now also allow empty secrets to be added to the VPN setting. For one, this avoids an assertion failure, where keyfile reader wouldn't check whether a secret key is set to the empty word. For data, it's more clear that we want to allow setting empty data values. VPN settings are only interpreted by the VPN plugin, so libnm and the daemon shouldn't prevent empty settings. It can be useful to distinguish between unset (NULL) and empty values. For secrets, it's less clear that empty secrets shall be allowed. I think it should. Of course, the empty secret likely isn't a correct nor valid secret. But libnm cannot validate the secrets anyway. It's up to the VPN plugin to handle this in any way they see fit. Also, already before, the user could set NM_SETTING_VPN_SECRETS to a string dictionary with empty passwords. So, the API didn't fully prevent that. Only certain API wouldn't play along.
| * libnm: allow setting empty vpn.data itemThomas Haller2020-04-042-8/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, nm_setting_vpn_add_data_item() would reject empty data values. This leads for example to an assertion failure, if you write a keyfile that assigns an empty value to a key. Keyfile reader would not check that the value is non-empty before calling nm_setting_vpn_add_data_item(). Anyway, I think we should not require having non-empty data elements. It's an unnecessary and sometimes harmful restriction. NetworkManager doesn't understand not care about the content of the vpn data. That is up the VPN plugins. Sometimes and empty value may be desirable. Also, the NM_SETTING_VPN_DATA property setter wouldn't filter out empty values either. So it was always possible to use some libnm API to set data with empty values. The restriction in nm_setting_vpn_add_data_item() was inconsistent.
| * libnm: ensure we have no empty secret keys in NMSettingVpnThomas Haller2020-04-041-5/+13
| | | | | | | | | | | | | | | | | | Also drop the g_warn_if_fail() from update_secret_dict(). We may get the variant from D-Bus, so avoiding this assertion (g_warn*() is an assertion!) would require us to prevalidate the variant. That would be very cumbersome, and we would probably not want to handle that as an error and silently ignore them anyway. Just shut up.
| * libnm: ensure we have no empty data keys in NMSettingVpnThomas Haller2020-04-041-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Ensure that the data hash doesn't contain keys with empty key-name. It just doesn't make sense, and will lead to potential problems later, if we would allow this to happen. For example, keyfile writer may naively try to set all keys, without checking for empty keys. That may lead to assertion failures or worse, later on. Don't allow that. Also, assert against non-empty keys in nm_setting_vpn_get_data_item() and nm_setting_vpn_remove_data_item(). This stricter handling is a change in behavior, however it would have always been a bug trying to refer to empty key names. So, this assertion will only help to find those bugs.
| * libnm: allocate "secrets" hash for NMSettingVpn lazilyThomas Haller2020-04-041-36/+56
| |
| * libnm: allocate "data" hash for NMSettingVpn lazilyThomas Haller2020-04-041-29/+47
| | | | | | | | | | | | | | | | | | We always initialized priv->data in nm_setting_vpn_init(), but usually soon after this hash would be replaced by NM_SETTING_VPN_DATA property setter. Avoid that. Allow for priv->data to be %NULL, which of course has the meaning that no keys are set.
| * libnm: fail get_secret_flags(),set_secret_flags() for empty secret name in ↵Thomas Haller2020-04-041-0/+16
| | | | | | | | NMSettingVpn
| * libnm: make NMSettingVpn's foreach_item_helper() robust against changesThomas Haller2020-04-041-29/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When we invoke the user's callback, be more robust about the user modifying or unreferencing the NMSettingVpn, while iterating. While it would be odd to modify the NMSettingVpn from inside the foreach callback, we should behave consistently and sensibly. That means, to ensure that the NMSettingVpn instance stays alive all the time, that we don't crash, and that we always iterate over the previously determined, planned list of keys. Also, avoid some unnecessary string copies, like the clone of the first key.
| * libnm: use streq() instead of strcmp() for NMSettingVpnThomas Haller2020-04-041-3/+3
| |
| * libnm: drop unrechable g_warn_if_fail() assertion from NMSettingVpn's ↵Thomas Haller2020-04-041-9/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | update_secret_dict() For one, this code was unreachable, because we checked these conditions already before. That aside, g_warn_*() is for all intended purposes an assertion. The caller probably gets the GVariant from an untrusted source (e.g. via D-Bus). Asserting here is not helpful. It's up to the caller to validate the argument. Or, in case the caller doesn't care, update_secret_dict() should just do the sensible thing. But be silent about it!
| * libnm: avoid strlen() to determine whether a string is emptyThomas Haller2020-04-041-7/+7
| | | | | | | | | | | | Yes, the compiler probably can optimize strlen() in these cases. That still doesn't make strlen() the right API to check whether a NUL terminated string is empty.
| * libnm: use NM_STR_HAS_SUFFIX() in nm-setting-vpn.c's aggregate()Thomas Haller2020-04-041-1/+1
| |
| * shared: add nm_g_hash_table_*() utils for accepting %NULL hash argumentThomas Haller2020-04-041-0/+20
| |
| * libnmm,shared: extract and move nm_utils_strdict_to_variant_ass() to sharedThomas Haller2020-04-043-47/+59
|/ | | | | | This is a helper function that converts a string dictionary to an "a{ss}" GVariant. It is generally useful, and should be independent from the caller.
* cli: merge branch 'th/cli-globals'Thomas Haller2020-04-049-49/+78
|\
| * cli: hide nm_cli global variable from public headersThomas Haller2020-04-043-5/+2
| |
| * cli: avoid using nm_cli global variable in print_data()Thomas Haller2020-04-044-21/+41
| |
| * cli: avoid passing full NmCli global variable to nm_cli_spawn_pager()Thomas Haller2020-04-045-12/+20
| | | | | | | | | | | | | | | | We should not use global variables, and we should minimize the state that we pass around. Instead of requiring the full NmCli struct in nm_cli_spawn_pager(), pass only the necessary data. This reduces our use of global variables.
| * cli: make nmc_meta_environment_arg const pointerThomas Haller2020-04-044-8/+8
| | | | | | | | | | Of course, we later pass the point on, where we need to cast the constness away again. This is more a reminder that we aren't suppost to change the variable.
| * cli: add and use nm_cli_global_readline global variableThomas Haller2020-04-044-6/+10
|/ | | | | | | | | We should try to avoid access to global variables. For libreadline callbacks we still need a global variable. Introduce a global variable nm_cli_global_readline, specially for this use. It makes the places clear where we use it, and discourages the use at other places, where we better avoid global variables.
* merge branch 'th/strbuf-v2'Thomas Haller2020-04-0411-71/+686
|\ | | | | | | https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/432
| * shared: use NMStrBuf in _nm_utils_enum_to_str_full()th/strbuf-v2Thomas Haller2020-04-031-10/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Just for showcase and to hit the code from the unit-tests that we have. Also, just to show, the following runs about 25 % faster than before, which isn't bad for such a simple replacement. { GType gtype = nm_test_general_color_flags_get_type (); const int N_RUN = 1000000; int i_run; guint8 c = 0; for (i_run = 0; i_run < N_RUN; i_run++) { gs_free char *str = NULL; str = _nm_utils_enum_to_str_full (gtype, i_run % 10, ",", NULL); c += str[0]; } return c % 3; } $ perf stat -r 200 -B libnm-core/tests/test-general Before: Performance counter stats for 'libnm-core/tests/test-general' (200 runs): 204.48 msec task-clock:u # 0.997 CPUs utilized ( +- 0.53% ) 0 context-switches:u # 0.000 K/sec 0 cpu-migrations:u # 0.000 K/sec 267 page-faults:u # 0.001 M/sec ( +- 0.05% ) 702,987,494 cycles:u # 3.438 GHz ( +- 0.54% ) 1,698,874,415 instructions:u # 2.42 insn per cycle ( +- 0.00% ) 410,394,229 branches:u # 2006.970 M/sec ( +- 0.00% ) 1,770,484 branch-misses:u # 0.43% of all branches ( +- 0.40% ) 0.20502 +- 0.00108 seconds time elapsed ( +- 0.53% ) After: Performance counter stats for 'libnm-core/tests/test-general' (200 runs): 155.71 msec task-clock:u # 0.996 CPUs utilized ( +- 0.50% ) 0 context-switches:u # 0.000 K/sec 0 cpu-migrations:u # 0.000 K/sec 266 page-faults:u # 0.002 M/sec ( +- 0.05% ) 539,994,118 cycles:u # 3.468 GHz ( +- 0.49% ) 1,116,016,733 instructions:u # 2.07 insn per cycle ( +- 0.00% ) 283,974,158 branches:u # 1823.760 M/sec ( +- 0.00% ) 1,377,786 branch-misses:u # 0.49% of all branches ( +- 0.43% ) 0.156255 +- 0.000786 seconds time elapsed ( +- 0.50% )
| * shared: pre-allocate GString with 16 bytes for _nm_utils_enum_to_str_full()Thomas Haller2020-04-031-1/+1
| | | | | | | | | | | | | | In the next commit, GString will be replaced by NMStrBuf. Then, we will pre-allocate a string buffer with 16 bytes, and measure the performance difference. To have it comparable, adjust the pre-allocation size also with GString.
| * shared: use NMStrBuf for implementing nm_utils_str_utf8safe_unescape()Thomas Haller2020-04-031-9/+8
| |
| * shared: use nm_utils_buf_utf8safe_unescape() for ↵Thomas Haller2020-04-031-6/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | nm_utils_str_utf8safe_unescape() nm_utils_buf_utf8safe_unescape() is almost the same as g_strcompress(), with the only difference is that if the string contains NUL escapes "\000", it will be handled correctly. In other words, g_strcompress() and nm_utils_str_utf8safe_unescape() can only unescape values, that contain no NUL escapes. That's why we added our own binary unescape function. As we already have our g_strcompress() variant, use it. It just gives it more testing and usage. Also, we have full control over it's behavior. For example, g_strcompress() issues a g_warning() when encountering a trailing '\\'. I think this makes it unsuitable to unescape untrusted data. Either the function should fail, or just make the best of it. Currently, our implementation does the latter.
| * shared: add NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET flagThomas Haller2020-04-033-16/+22
| | | | | | | | | | The new flag tells that as we re-allocate data buffers during escaping, we bzero the memory to avoid leaking secrets.
| * shared: add NMStrBuf utilThomas Haller2020-04-033-0/+276
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Our own implementation of a string buffer like GString. Advantages (in decreasing relevance): - Since we are in control, we can easily let it nm_explicit_bzero() the memory. The regular GString API cannot be used in such a case. While nm_explicit_bzero() may or may not be of questionable benefit, the problem is that if the underlying API counteracts the aim of clearing memory, it gets impossible. As API like NMStrBuf supports it, clearing memory is a easy as enable the right flag. This would for example be useful for example when we read passwords from a file or file descriptor (e.g. try_spawn_vpn_auth_helper()). - We have API like nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size); which accept a fixed size output buffer. This has the problem of how choosing the right sized buffer. With NMStrBuf such API could be instead nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, NMStrBuf *buf); which can automatically grow (using heap allocation). It would be easy to extend NMStrBuf to use a fixed buffer or limiting the maximum string length. The point is, that the to-string API wouldn't have to change. Depending on the NMStrBuf passed in, you can fill an unbounded heap allocated string, a heap allocated string up to a fixed length, or a static string of fixed length. NMStrBuf currently only implements the unbounded heap allocate string case, but it would be simple to extend. Note that we already have API like nm_utils_strbuf_*() to fill a buffer of fixed size. GString is not useable for that (efficiently), hence this API exists. NMStrBuf could be easily extended to replace this API without usability or performance penalty. So, while this adds one new API, it could replace other APIs. - GString always requires a heap allocation for the container. In by far most of the cases where we use GString, we use it to simply construct a string dynamically. There is zero use for this overhead. If one really needs a heap allocated buffer, NMStrBuf can easily embedded in a malloc'ed memory and boxed that way. - GString API supports inserting and removing range. We almost never make use of that. We only require append-only, which is simple to implement. - GString needs to NUL terminate the buffer on every append. It has unnecessary overhead for allowing a usage of where intermediate buffer contents are valid strings too. That is not the case with NMStrBuf: the API requires the user to call nm_str_buf_get_str() or nm_str_buf_finalize(). In most cases, you would only access the string once at the end, and not while constructing it. - GString always grows the buffer size by doubling it. I don't think that is optimal. I don't think there is one optimal approach for how to grow the buffer, it depends on the usage patterns. However, trying to make an optimal choice here makes a difference. QT also thinks so, and I adopted their approach in nm_utils_get_next_realloc_size().
| * shared: add nm_utils_get_next_realloc_size() helperThomas Haller2020-04-033-0/+222
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When growing a buffer by appending a previously unknown number of elements, the often preferable strategy is growing it exponentially, so that the amortized runtime and re-allocation costs scale linearly. GString just always increases the buffer length to the next power of two. That works. I think there is value in trying to find an optimal next size. Because while it doesn't matter in terms of asymptotic behavior, in practice a better choice should make a difference. This is inspired by what QT does ([1]), to take more care when growing the buffers: - QString allocates 4 characters at a time until it reaches size 20. - From 20 to 4084, it advances by doubling the size each time. More precisely, it advances to the next power of two, minus 12. (Some memory allocators perform worst when requested exact powers of two, because they use a few bytes per block for book-keeping.) - From 4084 on, it advances by blocks of 2048 characters (4096 bytes). This makes sense because modern operating systems don't copy the entire data when reallocating a buffer; the physical memory pages are simply reordered, and only the data on the first and last pages actually needs to be copied. Note that a QT is talking about 12 characters, so we use 24 bytes head room. [1] https://doc.qt.io/qt-5/containers.html#growth-strategies
| * shared: use nm_secret_mem_try_realloc_take() in nm_utils_fd_get_contents()Thomas Haller2020-04-031-29/+3
| |