Commit graph

29727 commits

Author SHA1 Message Date
Thomas Haller
d9fbfad9f4
libnm,core: merge branch 'th/route-blackhole'
https://bugzilla.redhat.com/show_bug.cgi?id=1937823
https://bugzilla.redhat.com/show_bug.cgi?id=2013587

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1083
2022-02-10 08:39:53 +01:00
Thomas Haller
948c2b0fb1
libnm/doc: describe routing-rules in man nm-settings-nmcli 2022-02-09 23:10:58 +01:00
Thomas Haller
7b1e9a5c3d
libnm/doc: list route attributes in man nm-settings-nmcli
IPv4:

       routes
           A list of IPv4 destination addresses, prefix length, optional IPv4
           next hop addresses, optional route metric, optional attribute. The
           valid syntax is: "ip[/prefix] [next-hop] [metric]
           [attribute=val]...[,ip[/prefix]...]". For example "192.0.2.0/24
           10.1.1.1 77, 198.51.100.0/24".

           Various attributes are supported:

           •   "cwnd" - an unsigned 32 bit integer.

           •   "initcwnd" - an unsigned 32 bit integer.

           •   "initrwnd" - an unsigned 32 bit integer.

           •   "lock-cwnd" - a boolean value.

           •   "lock-initcwnd" - a boolean value.

           •   "lock-initrwnd" - a boolean value.

           •   "lock-mtu" - a boolean value.

           •   "lock-window" - a boolean value.

           •   "mtu" - an unsigned 32 bit integer.

           •   "onlink" - a boolean value.

           •   "scope" - an unsigned 8 bit integer. IPv4 only.

           •   "src" - an IPv4 address.

           •   "table" - an unsigned 32 bit integer. The default depends on
               ipv4.route-table.

           •   "tos" - an unsigned 8 bit integer. IPv4 only.

           •   "type" - one of unicast, local, blackhole, unavailable,
               prohibit. The default is unicast.

           •   "window" - an unsigned 32 bit integer.

           For details see also `man ip-route`.

           Format: a comma separated list of routes

IPv6:

       routes
           A list of IPv6 destination addresses, prefix length, optional IPv6
           next hop addresses, optional route metric, optional attribute. The
           valid syntax is: "ip[/prefix] [next-hop] [metric]
           [attribute=val]...[,ip[/prefix]...]".

           Various attributes are supported:

           •   "cwnd" - an unsigned 32 bit integer.

           •   "from" - an IPv6 address with optional prefix. IPv6 only.

           •   "initcwnd" - an unsigned 32 bit integer.

           •   "initrwnd" - an unsigned 32 bit integer.

           •   "lock-cwnd" - a boolean value.

           •   "lock-initcwnd" - a boolean value.

           •   "lock-initrwnd" - a boolean value.

           •   "lock-mtu" - a boolean value.

           •   "lock-window" - a boolean value.

           •   "mtu" - an unsigned 32 bit integer.

           •   "onlink" - a boolean value.

           •   "src" - an IPv6 address.

           •   "table" - an unsigned 32 bit integer. The default depends on
               ipv6.route-table.

           •   "type" - one of unicast, local, blackhole, unavailable,
               prohibit. The default is unicast.

           •   "window" - an unsigned 32 bit integer.

           For details see also `man ip-route`.

           Format: a comma separated list of routes
2022-02-09 22:33:23 +01:00
Thomas Haller
35599b4349
tools: fix constructing XML by dropping broken pretty_xml()
I don't understand the code, but it mangles the XML.

There is no difference in the markup we have so far. But if you
have nested XML (like for description-docbook tag) there are cases
where this is wrong.

There is also no need to prettify anything. If you want pretty-formatted
XML, do it yourself, for example with

  $ tidy --indent yes --indent-spaces 4 --indent-attributes yes --wrap-attributes yes --input-xml yes --output-xml yes src/libnm-client-impl/nm-property-infos-nmcli.xml

I think this was initially done, because we had the tool in perl, and
when migrating, we wanted to generate the exactly same output. And it
was the same output, and it was fine for the input we have. But with
different input, it's wrong. Drop it now.
2022-02-09 20:26:34 +01:00
Thomas Haller
41a177486b
tools: re-use regular expression in process_data()
Yes, they get cached by the library already. Still, no need for
doing this repeatedly.
2022-02-09 20:26:22 +01:00
Thomas Haller
84598adddf
libnm: allow configuring blackhole/unreachable/prohibit routes 2022-02-09 19:13:05 +01:00
Thomas Haller
9ab53e561a
core/l3cfg: let NML3Cfg handle nodev (blackhole) routes
Certain route types (blackhole, unreachable, prohibit) are not tied to
an interface. They are thus global and we need to track them system wide
(or better: per network namespace). That is done by NMPRouteManager.

For the routing rules, it's NMDevice itself to track/untrack the rules.
That is done for historical reasons, at the time, NML3Cfg did not exit.
Now with NML3Cfg, it seems that also NML3Cfg should be the part that
handles nodev routes. One reason is that we want to move IP
functionality out of NMDevice. So callers (NMDevice) would just add
blackhole routes to the NML3ConfigData and let NML3Cfg handle them.

Still, to handle these routes is rather different from regular routes.
Normally, NML3Cfg tracks an object state (ObjStateData) for each address/route,
and it hooks into platform signals to update the os_plobj field. Those signals
are dispatched by NMNetns and are only per-ifindex. Hence, NML3Cfg
wouldn't be notified about those nodev routes. Consequently, there
os_plobj could not be (efficiently) maintained and there is no
ObjStateData for such routes.

Instead, all that NML3Cfg does is have the routes in the NML3ConfigData and
tell NMPRouteManager about them. Seems simple enough. The only question
is when should NMPRouteManager sync? For now, we sync when the
track/untracking brings any changes and during reapply. Which is
probably fine.
2022-02-09 19:13:05 +01:00
Thomas Haller
6255e0dcac
core: handle blackhole/unreachable/prohibit route types in core
Specifically, in nm_utils_ip_route_attribute_to_platform() and in
_l3_config_data_add_obj() handle such new route type. For the moment,
they cannot be stored in a valid NMSettingIPConfig, but later this will
be necessary.
2022-02-09 19:13:05 +01:00
Thomas Haller
e32bc6d248
core/l3cfg: rework generating list of routes in _l3_commit_one()
This will be required next, when we will have also routes without a
device. Split the generation of the route list out.
2022-02-09 19:13:05 +01:00
Thomas Haller
9e90bb0817
platform: improve way to prune dirty route-manager entries
The general idea is that when we have entries tracked by the
route-manager, that we can mark them all as dirty. Then, calling the
"track" function will reset the dirty flag. Finally, there is a method
to delete all dirty entries.

As we can lookup an entry with O(1) (using dictionaries), we can
sync the list of tracked objects with O(n). We just need to track
all the ones we care about, and then delete those that were not touched
(that is, are still dirty).

Previously, we had to explicitly mark all entries as dirty. We can do
better. Just let nmp_route_manager_untrack_all() mark the survivors as
dirty right away. This way, we can save iterating the list once.

It also makes sense because the only purpose of the dirty flag is to
aid this prune mechanism with track/untrack-all. So, untrack-all can
just help out, and leave the remaining entries dirty, so that the next
track does the right thing.
2022-02-09 19:13:05 +01:00
Thomas Haller
5489aa596b
platform: return boolean changed value from nmp_route_manager_track() 2022-02-09 19:13:05 +01:00
Thomas Haller
81f6ba8377
platform: return self from nmp_route_manager_ref()
It's just more convenient.
2022-02-09 19:13:04 +01:00
Thomas Haller
f315ca9e84
platform: track linked list of objects in NMPRouteManager by type
We now track up to three kinds of object types in NMPRouteManager.

There is only one place, where we need to iterate over all objects of
the same type (e.g. all ipv4-routes), and that is nmp_route_manager_sync().

Previously, we only had one GHashTable with all the object, and when
iterating we had to skip over them after checking the type. That has some
overhead, but OK.

The ugliness with iterating over a GHashTable is that the order is non
deterministic. We should have a defined order in which things happen. To
achieve that, track three different CList, one for each object type.
Also, I expect that to be slightly faster, as you only have to iterate
over the list you care about.
2022-02-09 19:13:04 +01:00
Thomas Haller
7c27c63bec
platform: extend NMPRouteManager to work for routes 2022-02-09 19:13:04 +01:00
Thomas Haller
2e04d64232
platform: use nm_pdirect_{hash,equal}() in "nmp-route-manager.c"
No need for a dedicated implementation just to compare two
indirect pointers.
2022-02-09 19:13:04 +01:00
Thomas Haller
cfdecf5e96
platform: use nm_g_slice_free() in "nmp-route-manager.c" 2022-02-09 19:13:04 +01:00
Thomas Haller
3e6c8d220a
platform: use NM_HASH_OBFUSCATE_PTR() in "nmp-route-manager.c"
NM_HASH_OBFUSCATE_PTR() is some snake-oil to not log raw pointer values.
It obviously makes debugging harder.

But we don't need to generate differently obfuscated pointer values.
At least, let most users use the same obfuscation, so that the values
are comparable.
2022-02-09 19:13:04 +01:00
Thomas Haller
1baa301047
platform: use __NMLOG_DEFAULT() in "nmp-route-manager.c" 2022-02-09 19:13:04 +01:00
Thomas Haller
75959e2f1a
platform: rename internals in "nmp-route-manager.c"
We will not only track (routing) rules, but also routes. Rename.
2022-02-09 19:13:04 +01:00
Thomas Haller
5b3e96451b
platform: drop lazy initialization _rules_init() of NMPRouteManager
Let's just always allocate the hash tables. We will likely need them,
and three hash tables are relatively cheap.
2022-02-09 19:13:04 +01:00
Thomas Haller
3996933c57
platform: rename "nmp-route-manager.h" to "nmp-rules-manager.h" 2022-02-09 19:13:03 +01:00
Thomas Haller
ea4f6d7994
platform: rename NMPRulesManager API to NMPRouteManager
Routes of type blackhole, unreachable, prohibit don't have an
ifindex/device. They are thus in many ways similar to routing rules,
as they are global. We need a mediator to keep track which routes
to configure.

This will be very similar to what NMPRulesManager already does for
routing rules. Rename the API, so that it also can be used for routes.

Renaming the file will be done next, so that git's rename detection
doesn't get too confused.
2022-02-09 19:13:03 +01:00
Thomas Haller
92f51c6b43
platform: add support for blackhole,unreachable,prohibit route type 2022-02-09 19:13:03 +01:00
Thomas Haller
7ad14b86f8
platform: add nm_platform_route_type_is_nodev() helper 2022-02-09 19:13:03 +01:00
Thomas Haller
d4ad9666bd
platform: don't treat ifindex zero special in nmp_lookup_init_object()
So far, certain NMObject types could not have an ifindex of zero. Hence,
nmp_lookup_init_object() took such an ifindex to mean lookup all objects
of that type.

Soon, we will support blackhole/unreachable/prohibit route types, which
have their ifindex set to zero. It is still useful to lookup those routes
types via nmp_lookup_init_object().

Change behaviour how to interpret the ifindex. Note that this also
affects various callers of nmp_lookup_init_object(). If somebody was
relying on the previous behavior, it would need fixing.
2022-02-09 19:13:03 +01:00
Thomas Haller
1123d3a5fb
platform: don't check for valid ifindex in _vt_cmd_obj_is_alive_ipx_route()
_vt_cmd_obj_is_alive_ipx_route() is called by nmp_object_is_alive().
Non-alive objects are not put into the cache.

That certainly makes sense for RTM_F_CLONED routes, because they are
generated ad-hoc during the `ip route get` request.

Checking for the ifindex is not necessary. For one, some route types
(blackhole, unreachable, prohibit) don't have an ifindex. Also, the
purpose of _vt_cmd_obj_is_alive_ipx_route() is not to validate the
object. Just don't create objects without an ifindex, if you think the
route needs an ifindex. Checking here is not useful.

We also don't check that other fields like rt_source are valid, so there
is no need to do it for the ifindex either.
2022-02-09 19:13:03 +01:00
Thomas Haller
b58711f20d
platform: don't print NUL gateway in nm_platform_ip[46]_route_to_string()
Currently, for NMPlatformIP[46]Route always has a gateway, even if it's
possibly set to 0.0.0.0/::. Not sure whether kernel has a further
distinction between no-gateway and all-zero gateway.

Anyway. For us, a gateway of 0.0.0.0/:: means the same as having no
gateway. We cannot differentiate the two (nor do we need to).

Don't print that in nm_platform_ip[46]_route_to_string().

Also, because we are going to add blackhole route types, which cannot
have a next-hop. But we do this change for all routes types, because
it makes sense in general (and also what `ip route show` prints).
2022-02-09 19:13:03 +01:00
Thomas Haller
596d1645e8
core: use IS_IPv4 variable in nm_utils_ip_route_attribute_to_platform()
It's what we do at many other places. Consistency.
2022-02-09 19:13:03 +01:00
Thomas Haller
8085c0121f
platform: rename variable "IS_IPv4" in platform code
The variable with this purpose is usually called "IS_IPv4".

It's upper case, because usually this is a const variable, and because
it reminds of the NM_IS_IPv4(addr_family) macro. That letter case
is unusual, but it makes sense to me for the special purpose that this
variable has.

Anyway. The naming of this variable is a different point. Let's
use the variable name that is consistent and widely used.
2022-02-09 19:13:03 +01:00
Thomas Haller
0413b1bf8a
libnm: rework validating route attributes to avoid duplicate check
_nm_ip_route_attribute_validate_all() validates all attributes together.
As such, it calls to nm_ip_route_attribute_validate(), which in turn
validates one attribute at a time.

Such full validation needs to check that (potentially conflicting)
attributes are valid together. Hence, _nm_ip_route_attribute_validate_all()
needs again peek into the attributes.

Refactor the code, so that we can extract the pieces that we need and
not need to parse them twice.
2022-02-09 19:13:02 +01:00
Thomas Haller
6f277d8fa6
libnm: change NMVariantAttributeSpec.str_type to work for attributes of any type
First of all, all of NMVariantAttributeSpec is internal API. We only
expose the typedef itself as public API, but not its fields nor
their meaning. So we can change things.

Change "str_type" to "type_detail", so that it can work for any kind of
attribute, not only for strings. Usually, we want to avoid special
cases and treat all attributes the same, based on their GVariant type.
But sometimes, it is necessary to do something special with an
attribute. This is what the "type_detail" encodes, but it's not only
relevant for strings.
2022-02-09 19:13:02 +01:00
Thomas Haller
00e4f21629
libnm: avoid parsing IP addresses twice in NMIPAddress/NMIPRoute API
Usually the normalization (canonicalize) and validation of the IP
address string both requires to parse the string. As we always do
validation first, we can use the parsed address and don't need to parse
it a second time.
2022-02-09 19:13:02 +01:00
Thomas Haller
6208a1bb84
libnm: reorder fields in NMIPAddress/NMIPRoute struct
Order the fields by their size, to minimize the alignment gaps.
I guess, that doesn't matter because the alignment of the heap
allocation is larger than what we can safe here. Still, there is
on reason to do it any other way.

Also, it's not possible via API to set family/prefix to values outside
their range, so an 8bit integer is always sufficient. And we don't want
that invariant to change. We don't ever want to allow the caller to set
values that are clearly invalid, and will assert against that early (g_return()).
Point is, we can do this and there is no danger of future problems.
And even if we will support larger values, it's all an implementation
detail anyway.
2022-02-09 19:13:02 +01:00
Thomas Haller
f65747f6e9
tests: let "run-nm-test.sh" fail with exit code 1 on failure
`git bisect run` is peculiar about the exit code:

  error: bisect run failed: exit code 134 from '...' is < 0 or >= 128

If we just "exec" the test, it usually will fail on an assert. That results
in SIGABRT or exit code 134. So out of the box that is annoying with
git-bisect.

Work around that and let the test wrapper always coerce any test failure
to exit code 1.
2022-02-09 19:13:02 +01:00
Thomas Haller
a1abb3ebdf
priv-helper: merge branch 'th/nm_priv_helper_dbus_name'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1091
2022-02-09 18:48:15 +01:00
Thomas Haller
d849807521
priv-helper: remove D-Bus Alias for "nm-priv-helper.service"
In systemd, it's common that a D-Bus activatable service references
`SystemdService=dbus-$BUSNAME.service` instead the real service name.
Together with an `[Install].Alias=dbus-$BUSNAME.service` directive,
this allowed to enable/disable D-Bus activation without uninstalling the
service altogether ([1]).

Currently, when we install the RPM then `nm-priv-helper.service` is not
enabled, consequently the alias is not created, and D-Bus activation
does not work. I guess, we should fix that by enabling the service in
the %post section or via a systemd preset? Dunno.

Anyway. It seems that nm-priv-helper.service is more of an
implementation detail of NetworkManager. It makes not sense for the user
to interact directly, or to enable/disable D-Bus activation (because
that is how it works).

So, drop the alias.

See-also: [1] https://docs.fedoraproject.org/en-US/packaging-guidelines/Systemd/#activation_dbus
2022-02-09 18:47:14 +01:00
Thomas Haller
16a45d07ed
priv-helper: fix D-Bus patch to not contain forbidden character '-'
"-" is not allowed as D-Bus path and interface name, and discouraged as
bus name. This cause nm-priv-helper to crash, because GDBus asserts the
the object path is valid.

Replace the '-' with '_'. This way, it's consistent with
"nm_dispatcher".

Fixes: d68ab6b8f0 ('nm-sudo: rename to nm-priv-helper')
2022-02-09 18:47:14 +01:00
Val Och
3b67b7768d
libnm: fix nm_client_add_and_activate_connection2_finish annotation
Mark out_result as out argument. Fixes an issue when using libnm bindings.

Fixes: fbb038af5e ('all: return output dictionary from "AddAndActivate2"')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1092
2022-02-09 18:29:33 +01:00
Thomas Haller
60153308fe
core/rfkill: merge branch 'th/rfkill-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1079
2022-02-08 18:59:06 +01:00
Thomas Haller
26e9deb831
core/rfkill: cleanup arguments for "rfkill-changed" signal
The signal parameters are G_TYPE_UINT. We should not assume that our
enums are a compatible integer type.

In practice of course they always were. Let's just be clear about when
we have an integer and when we have an enum.
2022-02-08 18:58:54 +01:00
Thomas Haller
aa15ec6090
core/rfkill: use nm_streq() in "nm-rfkill-manager.c" 2022-02-08 18:58:54 +01:00
Thomas Haller
e3e17f0b4b
core/rfkill: use CList to track Rfkill killswitches
GSList is almost always the wrong choice. We can just embed
the next pointers in the structure using the intrusive CList.
2022-02-08 18:58:53 +01:00
Thomas Haller
bc7a387072
core/rfkill: cleanup initializing Killswitch struct
- use slice allocator
- use designated initializers
- first determine all parameters in killswitch_new() before
  setting ks.
- drop unnecessary memset().
2022-02-08 18:58:53 +01:00
Thomas Haller
96abd25c72
core/rfkill: don't assert for valid string in rfkill_type_to_enum()
"str" comes from udev. This is not a trusted component, and we must not assert
for valid input.
2022-02-08 18:58:53 +01:00
Thomas Haller
a19ca08bcf
core/rfkill: rename rfkill_state_to_desc() to nm_rfkill_state_to_string() 2022-02-08 18:58:53 +01:00
Thomas Haller
6b001b0685
core/rfkill: add nm_rfkill_type_to_string() helper 2022-02-08 18:58:53 +01:00
Thomas Haller
3b7d861eef
core/rfkill: use "nm_auto_close" in _rfkill_update_system() to close FD 2022-02-08 18:58:53 +01:00
Thomas Haller
467b21afa7
core/rfkill: rename Rfkill related functions in "nm-manager.c"
Naming is important. Especially when we have a 8k LOC monster, that
manages everything.

Rename things related to Rfkill to give them a common prefix.

Also, move code around so it's beside each other.
2022-02-08 18:58:53 +01:00
Thomas Haller
858a0ee47f
core/rfkill: move immutable type description of Rfkill to global field
RadioState contained both the mutable user-data and meta-data about the
radio state. The latter is immutable. The parts that cannot change, should
be separate from those that can change. Move them to a separate array.

Of course, we only have on NMManager instance, so having these fields embedded
in NMManagerPrivate did not waste memory. This change is done, because immutable
fields should be const. In this case, they are now const global data, which
is even protected by the linker from accidental mutation.
2022-02-08 18:58:53 +01:00
Thomas Haller
454992ed85
core/rfkill: add "nm" prefix to RfKillState and RfKillType enums
Names in header files should have an "nm" prefix. We do that pretty
consistently. Fix the offenders RfKillState and RfKillType.

Also, rename the RfKillState enums to follow the type name. For example,
NM_RFKILL_STATE_SOFT_BLOCKED instead of RFKILL_SOFT_BLOCKED.

Also, when we camel-case a typedef (NMRfKillState) we would want that
the lower-case names use underscore between the words. So it should be
`nm_rf_kill_state_to_string()`. But that looks awkward. So the right solution
here is to also rename "RfKill" to "Rfkill". That make is consistent
with the spelling of the existing `NMRfkillManager` type and the
`nm-rfkill-manager.h` file.
2022-02-08 18:58:53 +01:00