summaryrefslogtreecommitdiff
path: root/src/platform
Commit message (Collapse)AuthorAgeFilesLines
* all: SPDX header conversionLubomir Rintel2019-09-1035-490/+35
| | | | | $ find * -type f |xargs perl contrib/scripts/spdx.pl $ git rm contrib/scripts/spdx.pl
* platforn/linux: don't fall back to WEXT for OLPC Meshlr/olpc-meshLubomir Rintel2019-09-071-9/+1
| | | | nl80211 offers the same functionality sans the bugs.
* wifi: add OLPC Mesh support via nl80211Lubomir Rintel2019-09-071-0/+67
|
* ipv6: set neighbor parameters from RAsBeniamino Galvani2019-08-302-0/+54
| | | | | | | | | | | | | | | | | | | | | | | | IPv6 router advertisement messages contain the following parameters (RFC 4861): - Reachable time: 32-bit unsigned integer. The time, in milliseconds, that a node assumes a neighbor is reachable after having received a reachability confirmation. Used by the Neighbor Unreachability Detection algorithm. A value of zero means unspecified (by this router). - Retrans Timer: 32-bit unsigned integer. The time, in milliseconds, between retransmitted Neighbor Solicitation messages. Used by address resolution and the Neighbor Unreachability Detection algorithm. A value of zero means unspecified (by this router). Currently NM ignores them; however, since it leaves accept_ra=1, the kernel parses RAs and applies those parameters for us [1]. In the next commit kernel handling of RAs will be disabled, so let NM set those neighbor-related parameters. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv6/ndisc.c?h=v5.2#n1353
* wifi: expose IBSS_RSN capabilityBeniamino Galvani2019-08-261-0/+3
| | | | | | | The new capability indicates whether the device supports WPA2/RSN in an IBSS (ad-hoc) network. https://bugzilla.gnome.org/show_bug.cgi?id=757823
* shared,all: return boolean success from nm_utils_file_get_contents()Thomas Haller2019-08-082-27/+53
| | | | | | | | | | | | | | | | | | | | | | ... and nm_utils_fd_get_contents() and nm_utils_file_set_contents(). Don't mix negative errno return value with a GError output. Instead, return a boolean result indicating success or failure. Also, optionally - output GError - set out_errsv to the positive errno (or 0 on success) Obviously, the return value and the output arguments (contents, length, out_errsv, error) must all agree in their success/failure result. That means, you may check any of the return value, out_errsv, error, and contents to reliably detect failure or success. Also note that out_errsv gives the positive(!) errno. But you probably shouldn't care about the distinction and use nm_errno_native() either way to normalize the value.
* platform/tests: relax assertion for platform signal in test_slave()Thomas Haller2019-08-021-1/+1
| | | | | | | | | | Seen on gitlab-ci. NMPlatformSignalAssert: ../src/platform/tests/test-link.c:260, test_slave(): failure to accept signal [0,2] times: link-changed-changed ifindex 15 (3 times received) ERROR: src/platform/tests/test-link-linux - too few tests run (expected 76, got 6) ERROR: src/platform/tests/test-link-linux - exited with status 133 (terminated by signal 5?) (cherry picked from commit 483de2bb93ff66afc439f89d3ce8f539acd87867)
* platform: drop checks for failure of nl80211_alloc_msg()Thomas Haller2019-08-021-9/+5
| | | | | | | | | nl80211_alloc_msg() just allocates some memory, using glib's allocators. Hence it cannot fail, and we don't need to check for that. Drop the unnecessary %NULL checks. (cherry picked from commit 990a7bee9d35c19420fe87c44293e5c125cde2e5)
* platform: avoid coverity warning about not checking nla_nest_start() resultThomas Haller2019-08-021-0/+2
| | | | | | | | | | | Usually we check the result of nla_nest_start(). Also, in most cases where this function would return %NULL, it's an actual bug. That is, because our netlink message is allocated with a large buffer, and in most cases we append there a well known, small amount of data. To make coverity happy, handle the case and assert. (cherry picked from commit 243458836adcdb4652bcb5871b53e6f65b510985)
* core/trivial: fix whitespaceThomas Haller2019-08-021-3/+3
| | | | (cherry picked from commit 2ea3c237235312f75498bd55deca128036029b31)
* platform: add NMP_OBJECT_CAST_LNK_WIREGUARD() macroThomas Haller2019-07-291-0/+1
|
* platform: cleanup NMPObject cast macrosThomas Haller2019-07-291-90/+15
|
* platform: make plobj argument of nmp_object_new() void pointerThomas Haller2019-07-292-2/+2
| | | | | | | | NMPlatformObject is a base-type of all actual platform structs. We very seldomly use this type directly. Most callers that pass the plobj to nmp_object_new() will need to cast it. Make the varible a void pointer to not require the cast.
* platform: allow AF_UNSPEC for nmp_lookup_init_object_by_addr_family()Thomas Haller2019-07-291-1/+4
|
* setting-wireless: allow Mesh modeLubomir Rintel2019-07-292-5/+13
|
* platform: add nm_platform_lookup_object_by_addr_family() utilThomas Haller2019-07-271-0/+11
|
* all: codespell fixesLubomir Rintel2019-07-241-1/+1
| | | | | Codespel run with the same arguments as described in commit 58510ed56679 ('docs: misc. typos pt2').
* platform/netlink: mark nested netlink attribute with NLA_F_NESTEDThomas Haller2019-07-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | Kernel 5.2 is adding stricter checking for netlink messages. In particular, for certain API it checks now that NLA_F_NESTED flag is set for nested attributes ([1]). Note that libnl3 does not ever set this flag, and since our netlink implementation is copied from there, certain netlink messages are now rejected as invalid. On the other hand, libmnl always adds this flag ([2]). So we should do that as well. In particular, this affects the WireGuard netlink API causing request from NetworkManager to be rejected ([3]). [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b424e432e770d6dd572765459d5b6a96a19c5286 [2] https://git.netfilter.org/libmnl/tree/src/attr.c?id=5937dfcb0185f5cb9cf275992ea701ec4e619d9c#n535 [3] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/212 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/210
* libnm,core: use nm_utils_clock_gettime_*() instead of clock_gettime()Thomas Haller2019-07-231-11/+9
| | | | | | | We usually want to combine the fields from "struct timespec" to have one timestamp in either nanoseconds or milliseconds. Use nm_utils_clock_gettime_*() util for that.
* policy-routing: take ownership of externally configured rulesThomas Haller2019-07-163-24/+109
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | IP addresses, routes, TC and QDiscs are all tied to a certain interface. So when NetworkManager manages an interface, it can be confident that all related entires should be managed, deleted and modified by NetworkManager. Routing policy rules are global. For that we have NMPRulesManager which keeps track of whether NetworkManager owns a rule. This allows multiple connection profiles to specify the same rule, and NMPRulesManager can consolidate this information to know whether to add or remove the rule. NMPRulesManager would also support to explicitly block a rule by tracking it with negative priority. However that is still unused at the moment. All that devices do is to add rules (track with positive priority) and remove them (untrack) once the profile gets deactivated. As rules are not exclusively owned by NetworkManager, NetworkManager tries not to interfere with rules that it knows nothing about. That means in particular, when NetworkManager starts it will "weakly track" all rules that are present. "weakly track" is mostly interesting for two cases: - when NMPRulesManager had the same rule explicitly tracked (added) by a device, then deactivating the device will leave the rule in place. - when NMPRulesManager had the same rule explicitly blocked (tracked with negative priority), then it would restore the rule when that block gets removed (as said, currently nobody actually does this). Note that when restarting NetworkManager, then the device may stay and the rules kept. However after restart, NetworkManager no longer knows that it previously added this route, so it would weakly track it and never remove them again. That is a problem. Avoid that, by whenever explicitly tracking a rule we also make sure to no longer weakly track it. Most likely this rule was indeed previously managed by NetworkManager. If this was really a rule added by externally, then the user really should choose distinct rule priorities to avoid such conflicts altogether.
* platform/tests: relax check for accepting platform signalsThomas Haller2019-07-091-1/+1
| | | | | | | | | | | | | | nmtst: initialize nmtst_get_rand() with NMTST_SEED_RAND=0 /link/bogus: OK /link/loopback: OK /link/internal: OK /link/external: OK /link/software/bridge: OK /link/software/bond: OK /link/software/team: NMPlatformSignalAssert: ../src/platform/tests/test-link.c:331, test_slave(): failure to accept signal [0,2] times: 'link-changed-changed' ifindex 15 (3 times received) --- stderr --- /builds/NetworkManager/NetworkManager/tools/run-nm-test.sh: line 264: 106682 Trace/breakpoint trap --quiet --error-exitcode= --leak-check=full --gen-suppressions=all --num-callers=100 --log-file= The test failed. Also check the valgrind log at '/builds/NetworkManager/NetworkManager/build/src/platform/tests/test-link-linux.valgrind-log'
* core: drop nm_platform_link_get_address_as_bytes()Beniamino Galvani2019-07-052-12/+14
| | | | | | Drop nm_platform_link_get_address_as_bytes() and introduce nmp_link_address_get_as_bytes() so that it becomes possible to obtain also the broadcast address without an additional lookup of the link.
* platform: add nm_platform_sysctl_ip_conf_get_rp_filter_ipv4()Thomas Haller2019-06-172-0/+45
|
* platform/tests: relax assertion for accepting signals in ↵Thomas Haller2019-06-161-1/+1
| | | | | | /link/software/bridge test /link/software/bridge: NMPlatformSignalAssert: ../src/platform/tests/test-link.c:289, test_slave(): failure to accept signal [0,2] times: 'link-changed-changed' ifindex 10 (3 times received)
* platform/tests: relax assertion for accepting signals in /link/software/bond ↵Thomas Haller2019-06-141-1/+1
| | | | | | test /link/software/bond: NMPlatformSignalAssert: ../src/platform/tests/test-link.c:243, test_slave(): failure to accept signal [1,2] times: link-changed-changed ifindex 13 (3 times received)
* all: drop emacs file variables from source filesThomas Haller2019-06-1130-30/+0
| | | | | | | | | | | | | | | | | | | | | | We no longer add these. If you use Emacs, configure it yourself. Also, due to our "smart-tab" usage the editor anyway does a subpar job handling our tabs. However, on the upside every user can choose whatever tab-width he/she prefers. If "smart-tabs" are used properly (like we do), every tab-width will work. No manual changes, just ran commands: F=($(git grep -l -e '-\*-')) sed '1 { /\/\* *-\*- *[mM]ode.*\*\/$/d }' -i "${F[@]}" sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}" Check remaining lines with: git grep -e '-\*-' The ultimate purpose of this is to cleanup our files and eventually use SPDX license identifiers. For that, first get rid of the boilerplate lines.
* platform: avoid heap allocating string buffer for printing link flagsThomas Haller2019-06-113-15/+46
|
* platform: handle IFLA_BROADCAST in platform cache for linksThomas Haller2019-06-115-58/+131
| | | | | | While at it, rename the "addr" field to "l_address". The term "addr" is used over and over. Instead we should use distinct names that make it easier to navigate the code.
* tests/trivial: rename nmtst_get_rand_int() to nmtst_get_rand_uint32()Thomas Haller2019-06-114-63/+63
| | | | | | | | nmtst_get_rand_int() was originally named that way, because it calls g_rand_int(). But I think if a function returns an uint32, it should also be named that way. Rename.
* platform: avoid compiler error passing NMP_OBJECT_CAST_OBJ_WITH_IFINDEX() to ↵Thomas Haller2019-05-291-1/+1
| | | | | | | | | | | | nm_hash_update_vals() Clang (3.4.2-9.el7) on CentOS 7.6 fails related to nm_hash_update_vals(). Clang seems to dislike passing certain complex arguments to typeof(). I'd prefer to fix nm_hash_update_vals() to not have this problem, but I don't know how. This works around the issue.
* platform: make nm_platform_kernel_support_get() macro an inline functionThomas Haller2019-05-291-22/+22
| | | | | | | | | | | | | | | | clang (3.4.2-9.el7) on CentOS 7.6 fails related to nm_hash_update_vals(). I am not even quoting the error message, it's totally non-understandable. nm_hash_update_vals() uses typeof(), and in some obscure cases, clang dislikes when the argument itself is some complex macro. I didn't fully understand why, but this works around it. I would prefer to fix nm_hash_update_vals() to not have this limitation. But I don't know how. There is probably no downside to have this an inline function instead of a macro.
* core: set number of SR-IOV VFs asynchronouslyBeniamino Galvani2019-05-283-54/+125
| | | | | | | When changing the number of VFs the kernel can block for very long time in the write() to sysfs, especially if autoprobe-drivers is enabled. Turn the nm_platform_link_set_sriov_params() into an asynchronous function.
* platform: add async sysctl set functionBeniamino Galvani2019-05-284-12/+355
| | | | Add a function to asynchronously set sysctl values.
* platform: print sysctl absolute path when pathid is NULLBeniamino Galvani2019-05-281-3/+3
| | | | @pathid can be NULL, in such case print the absolute path.
* platform: use 'self' argument name for platform functionsBeniamino Galvani2019-05-282-103/+98
| | | | Uniform all functions to use 'self' as first argument.
* gitignore: merge gitignore filesThomas Haller2019-05-191-16/+0
| | | | | | | | | For the most part, we only have one main .gitignore file. There were a few nested files, merge them into the main file. I find it better to have only one gitignore file, otherwise the list of ignored files is spread out through the working directory.
* platform/tests: rename platform's "test-general.c"Thomas Haller2019-05-183-12/+14
| | | | | | | | | | | | | | | Older versions of meson don't like building multiple artifacts with the same name (even if they are in different directories). We have multiple tests called "test-general.c", and it would be natural to compile a test binary of the same name. Meson encountered an error in file src/tests/meson.build, line 14, column 2: Tried to create target "test-general", but a target of that name already exists. It's generally a bad idea to have in our source tree multiple files with the same name. Rename the test. Fixes: 16cd84d346f1 ('build/meson: rename platform tests to use same name as autotools'):
* build/meson: rename platform tests to use same name as autotoolsThomas Haller2019-05-171-6/+3
| | | | | | | | | | | | | | | | | | First of all, all file names in our source-tree should be unique. We should not have stuff like "libnm-core/tests/test-general.c" and "src/tests/test-general.c". The problem here are the C source files, and consequently also the test binaries have duplicate names. We should avoid that in general. However, our binaries should have a matching name with the C source. If "test-general.c" is not good enough, that needs renaming. Not building "platform-test-general" out of it. On the other hand, all our tests should have a filename "*/tests/test-*", like they do for autotools. Rename the meson platform tests. It's also important because "tools/run-nm-test.sh" relies on the test name to workaround valgrind warnings.
* tests: use "/run" instead of "/var/run"Thomas Haller2019-05-171-3/+3
|
* platform: avoid valgrind warning about uninitialised memory in _ioctl_call()Thomas Haller2019-05-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ==6207== Syscall param ioctl(SIOCETHTOOL) points to uninitialised byte(s) ==6207== at 0x514603B: ioctl (syscall-template.S:78) ==6207== by 0x19FC2F: _ioctl_call (nm-platform-utils.c:183) ==6207== by 0x1A026B: _ethtool_call_handle (nm-platform-utils.c:319) ==6207== by 0x1A031F: ethtool_get_stringset (nm-platform-utils.c:378) ==6207== by 0x1A03BC: ethtool_get_stringset_index (nm-platform-utils.c:414) ==6207== by 0x1A181E: nmp_utils_ethtool_supports_vlans (nm-platform-utils.c:912) ==6207== by 0x1756D7: link_supports_vlans (nm-linux-platform.c:6508) ==6207== by 0x1A81D8: nm_platform_link_supports_vlans (nm-platform.c:1536) ==6207== by 0x14B96B: test_internal (test-link.c:602) ==6207== by 0x4F5C18D: test_case_run (gtestutils.c:2597) ==6207== by 0x4F5C18D: g_test_run_suite_internal (gtestutils.c:2685) ==6207== by 0x4F5BF33: g_test_run_suite_internal (gtestutils.c:2697) ==6207== by 0x4F5C679: g_test_run_suite (gtestutils.c:2772) ==6207== by 0x4F5C694: g_test_run (gtestutils.c:2007) ==6207== by 0x166B4D: main (test-common.c:2092) ==6207== Address 0x1ffeffeecf is on thread 1's stack ==6207== in frame #1, created by _ioctl_call (nm-platform-utils.c:110) ==6207== "ifname" is the stack-allocated array "known_ifnames" of suitable IFNAMSIZ bytes. But it may not be fully initialized, so using memcpy() to copy the string leads to unintialized warning. We really should only copy the valid bytes, either with strcpy() or our nm_utils_ifname_cpy() wrapper. Fixes: 856322562eff ('platform/ethtool,mii: retry ioctl when interface name was renamed for ehttool/mii')
* platform: use memset() to initialize ifr struct in _ioctl_call()Thomas Haller2019-05-161-3/+1
| | | | | | | | | "struct ifreq" contains a union field, and initalizing the struct is not guaranteed to fill all bytes with zero (it only sets the first union member to zero). Since we later return the entire struct, ensure that it's initialized to all zero by using memset().
* core: don't log plain pointer values for singletonsThomas Haller2019-05-131-1/+2
| | | | Logging pointer values allows to defeat ASLR. Don't do that.
* device/trivial: add comment about lifetime of "kind" in tc_commit()th/various-cleanup-platform-libnmThomas Haller2019-05-073-0/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In general, all fields of public NMPlatform* structs must be plain/simple. Meaning: copying the struct must be possible without caring about cloning/duplicating memory. In other words, if there are fields which lifetime is limited, then these fields cannot be inside the public part NMPlatform*. That is why - "NMPlatformLink.kind", "NMPlatformQdisc.kind", "NMPlatformTfilter.kind" are set by platform code to an interned string (g_intern_string()) that has a static lifetime. - the "ingress_qos_map" field is inside the ref-counted struct NMPObjectLnkVlan and not NMPlatformLnkVlan. This field requires managing the lifetime of the array and NMPlatformLnkVlan cannot provide that. See also for example NMPClass.cmd_obj_copy() which can deep-copy an object. But this is only suitable for fields in NMPObject*. The purpose of this rule is that you always can safely copy a NMPlatform* struct without worrying about the ownership and lifetime of the fields (the field's lifetime is unlimited). This rule and managing of resource lifetime is the main reason for the NMPlatform*/NMPObject* split. NMPlatform* structs simply have no mechanism for copying/releasing fields, that is why the NMPObject* counterpart exists (which is ref-counted and has a copy and destructor function). This is violated in tc_commit() for the "kind" strings. The lifetime of these strings is tied to the setting instance. We cannot intern the strings (because these are arbitrary strings and interned strings are leaked indefinitely). We also cannot g_strdup() the strings, because NMPlatform* is not supposed to own strings. So, just add comments that warn about this ugliness. The more correct solution would be to move the "kind" fields inside NMPObjectQdisc and NMPObjectTfilter, but that is a lot of extra effort.
* platform: merge _add_action(), _add_action_simple() and _add_action_mirred() ↵Thomas Haller2019-05-071-79/+46
| | | | | | | | | | | | | into _nl_msg_new_tfilter() There is only one caller, hence it's simpler to see it all in one place. I prefer this, because then I can read the code top to bottom and see what's happening, without following helper functions. Also, this way we can "reuse" the nla_put_failure label and assertion. Previously, if the assertion was hit we would not rewind the buffer but continue constructing the message (which is already borked). Not that it matters too much, because this was on an "failed-assertion" code path.
* platform: assert for out-of-memory in netlink codeThomas Haller2019-05-073-15/+15
| | | | | | These lines can be reached if the allocated buffer is too small to hold the netlink message. That is actually a bug that we need to fix. Assert.
* platform: use bool bitfields in NMPlatformActionMirred structureThomas Haller2019-05-072-13/+14
| | | | | | | | | | | Arguably, the structure is used inside a union with another (larger) struct, hence no memory is saved. In fact, it may well be slower performance wise to access a boolean bitfield than a gboolean (int). Still, boolean fields in structures should be bool:1 bitfields for consistency.
* libnm: rename "memory" parameter of fq_codel QDisc to "memory_limit"Thomas Haller2019-05-073-9/+9
| | | | | | | | Kernel calls the netlink attribute TCA_FQ_CODEL_MEMORY_LIMIT. Likewise, iproute2 calls this "memory_limit". Rename because TC parameters are inherrently tied to the kernel implementation and we should use the familiar name.
* platform: fix handling of default value for TCA_FQ_CODEL_CE_THRESHOLDThomas Haller2019-05-073-4/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | iproute2 uses the special value ~0u to indicate not to set TCA_FQ_CODEL_CE_THRESHOLD in RTM_NEWQDISC. When not explicitly setting the value, kernel treats the threshold as disabled. However note that 0xFFFFFFFFu is not an invalid threshold (as far as kernel is concerned). Thus, we should not use that as value to indicate that the value is unset. Note that iproute2 uses the special value ~0u only internally thereby making it impossible to set the threshold to 0xFFFFFFFFu). But kernel does not have this limitation. Maybe the cleanest way would be to add another field to NMPlatformQDisc: guint32 ce_threshold; bool ce_threshold_set:1; that indicates whether the threshold is enable or not. But note that kernel does: static void codel_params_init(struct codel_params *params) { ... params->ce_threshold = CODEL_DISABLED_THRESHOLD; static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) { ... if (tb[TCA_FQ_CODEL_CE_THRESHOLD]) { u64 val = nla_get_u32(tb[TCA_FQ_CODEL_CE_THRESHOLD]); q->cparams.ce_threshold = (val * NSEC_PER_USEC) >> CODEL_SHIFT; } static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb) { ... if (q->cparams.ce_threshold != CODEL_DISABLED_THRESHOLD && nla_put_u32(skb, TCA_FQ_CODEL_CE_THRESHOLD, codel_time_to_us(q->cparams.ce_threshold))) goto nla_put_failure; This means, kernel internally uses the special value 0x83126E97u to indicate that the threshold is disabled (WTF). That is because (((guint64) 0x83126E97u) * NSEC_PER_USEC) >> CODEL_SHIFT == CODEL_DISABLED_THRESHOLD So in kernel API this value is reserved (and has a special meaning to indicate that the threshold is disabled). So, instead of adding a ce_threshold_set flag, use the same value that kernel anyway uses.
* platform: fix handling of fq_codel's memory limit default valueThomas Haller2019-05-073-3/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The memory-limit is an unsigned integer. It is ugly (if not wrong) to compare unsigned values with "-1". When comparing with the default value we must also use an u32 type. Instead add a define NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET. Note that like iproute2 we treat NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET to indicate to not set TCA_FQ_CODEL_MEMORY_LIMIT in RTM_NEWQDISC. This special value is entirely internal to NetworkManager (or iproute2) and kernel will then choose a default memory limit (of 32MB). So setting NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET means to leave it to kernel to choose a value (which then chooses 32MB). See kernel's net/sched/sch_fq_codel.c: static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) { ... q->memory_limit = 32 << 20; /* 32 MBytes */ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) ... if (tb[TCA_FQ_CODEL_MEMORY_LIMIT]) q->memory_limit = min(1U << 31, nla_get_u32(tb[TCA_FQ_CODEL_MEMORY_LIMIT])); Note that not having zero as default value is problematic. In fields like "NMPlatformIP4Route.table_coerced" and "NMPlatformRoutingRule.suppress_prefixlen_inverse" we avoid this problem by storing a coerced value in the structure so that zero is still the default. We don't do that here for memory-limit, so the caller must always explicitly set the value.
* platform: fix nm_platform_qdisc_to_string()Thomas Haller2019-05-071-1/+4
| | | | | When using nm_utils_strbuf_*() API, the buffer gets always moved to the current end. We must thus remember and return the original start of the buffer.