diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f9b3dc02cb..c9da4fd7b1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,13 +9,62 @@ Check out website https://networkmanager.dev and our [GNOME page](https://wiki.g
The release tarballs can be found at [download.gnome.org](https://download.gnome.org/sources/NetworkManager/).
-Our mailing list is networkmanager@lists.freedesktop.org ([archive](https://lists.freedesktop.org/archives/networkmanager/),
-[old-archive](https://mail.gnome.org/archives/networkmanager-list/)).
+Find our available communication channels at https://networkmanager.dev/community/.
-Find us on IRC channel `#nm` on Libera.Chat.
-Report issues and send patches via [gitlab.freedesktop.org](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/)
-or our mailing list.
+Report issues
+-------------
+
+Report issues or feature requests in our [Gitlab's issue tracker](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues)
+or our maling list.
+
+For bug reports usually NetworkManager's logs will be needed to understand the
+problem. Attach the full logs to the issue. For WiFi related issues, attach also
+the logs from wpa_supplicant, or iwd if you are using it (i.e.
+`journalctl -u NetworkManager -u wpa_supplicant`).
+
+To get more useful logs, increase the log level as explained in
+["logging SECTION" in NetworkManager.conf](https://networkmanager.dev/docs/api/latest/NetworkManager.conf.html).
+
+Logfiles contain no passwords and little sensitive information, but please
+check before posting the file online. The script [anonymize-logs.py](contrib/scripts/anonymize-logs.py)
+can do some basic data anonymization but makes a bit harder to analyze the logs
+and you still need to review them. You can also personally hand over the logfile
+to a NM developer to treat it confidential.
+
+
+Contribute
+----------
+
+Send patches to our repository at [gitlab.freedesktop.org](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/).
+If you are willing to contribute, please read these guidelines first:
+
+- Find bugs or features to work on in our [Gitlab's issue tracker](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues).
+
+- Work on any issue you want, but please put a comment to indicate that you are
+ willing to work on it so others don't do the same work in parallel, or to
+ check whether anyone is already doing so.
+
+- Issues marked as `help-wanted` are those where the NetworkManager developers
+ are explicitly asking for contributors' help, probably due to lack of capacity
+ to work on it.
+
+- Issues marked as `good-first-issue` indicate that they are probably quite
+ simple fixes, well suited for first time contributors.
+
+- Contributions for features or bugs not reported in the issue tracker are also
+ welcome, but if they require a high amount of work, it is always better to
+ open an issue explaining what you intend to do first. That way, you won't
+ waste your valuable time if your idea doesn't fit well into the project or a
+ different approach would be desirable.
+
+- Reference related issues in your Merge Request description, and if the issue
+ gets resolved with it, indicate it with a line `Resolves: https://issue-url`.
+ Please use full URLs because they are clickable both from the web UI and from
+ the terminal.
+
+- Read the rest of this document to learn about the code style, code
+ organization, tests and other useful stuff.
Documentation
@@ -218,6 +267,7 @@ Code Structure
`./tools`- tools for generating the intermediate files or merging the file.
+
Cscope/ctags
---------------------------
@@ -420,6 +470,7 @@ To resync our local notes use:
```
$ git fetch origin refs/notes/bugs:refs/notes/bugs -f
```
-### Testing NetworkManager with nm-in-container script.
-See [the readme](tools/nm-in-container/README.md) for details.
+### Testing NetworkManager with nm-in-container or nm-in-vm scripts.
+
+See [the readme](tools/nm-guest-data/README.md) for details.
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index 161dd40a41..2eeb75b0ec 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -1,3 +1,45 @@
+Triaging issues
+---------------
+
+Issue tracker: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues
+
+Help other maintainers with the triage following these guidelines. This way, it
+will be easier to find issues that require attention.
+
+- Assign an issue to yourself if you are going to take care of providing the
+ required help. Assign it to another person if he/she is more suitable to help,
+ but do this quite rarely so we take care of not overloading to anyone.
+
+- Add suitable labels to indicate the state of open issues:
+
+ - `need-info`: waiting for info or feedback from anyone.
+
+ - `need-discussion`: something is not clear about what to do, or about if
+ something has to be done at all. The problem should be discussed by the
+ maintainers and/or with the reporter and/or other interested parts.
+
+ - `triaged`: if the problem is properly explained and understood. Add also
+ one of the labels `bug` or `RFE` as corresponds.
+
+ - `help-wanted`: request external contributors to work on this. If it's a
+ simple fix, add `good-first-issue` too.
+
+ - `work-in-progress`: anyone is already working on a Merge Request, so others.
+
+ - `blocked`: the issue is waiting for something that blocks its progress
+
+ - `close-proposed`: there are good reasons to reject the request (explain
+ those reasons when adding the label). If after a reasonable time there is no
+ additional info that is good enouch to reconsider it, the issue will be
+ closed.
+ It is not mandatory to always use this tag before closing an issue, but
+ usually desirable.
+
+- Close an issue if the problem is already solved, either via a code fix or via
+ some information that has been provided. Also if the request is clearly
+ incorrect or doesn't fit at all in the project.
+
+
Merging Merge Requests
----------------------
diff --git a/README.md b/README.md
index 1676c2d6e7..7eed9c9f80 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,5 @@
-******************
-NetworkManager core daemon has moved to gitlab.freedesktop.org!
-
-git clone https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
-******************
-
+NetworkManager
+==============
Networking that Just Works
--------------------------
@@ -31,7 +27,8 @@ network. NetworkManager will _never_ activate a connection that is not in this
list, or that the user has not directed NetworkManager to connect to.
-How it works:
+How it works
+------------
The NetworkManager daemon runs as a privileged service (since it must access
and control hardware), but provides a D-Bus interface on the system bus to
@@ -56,7 +53,34 @@ link-local addresses. Most communication with these daemons occurs, again,
via D-Bus.
+How to use it
+-------------
+
+Install NetworkManager with your distribution's package manager.
+
+As NetworkManager is actually a daemon that runs in the background, you need to
+use one of the many existing client programs to interact with it.
+
+Terminal clients:
+- `nmcli`: advanced command line client that gives you full control over all the
+ aspects of NetworkManager, developed as part of the NetworkManager project.
+- `nmtui`: text-based user interface (TUI) client. Also for the terminal, but
+ interactive and more user friendly, also part of the NetworkManager project.
+- [`nmstate`][1]: declarative network API and command line tool that uses
+ NetworkManager as backend.
+- Ansible: use the [network-role][2] in your playbooks
+
+GUI clients
+- `nm-connection-editor` and `nm-applet`: basic GUI interfaces developed by
+ the NetworkManager project.
+- GNOME shell: interacts with NetworkManager via its default settings panel
+ `gnome-control-center`
+- KDE Plasma: interacts with NetworkManager via its default settings panel
+ and `plasma-nm`
+
+
Why doesn't my network Just Work?
+---------------------------------
Driver problems are the #1 cause of why NetworkManager sometimes fails to
connect to wireless networks. Often, the driver simply doesn't behave in a
@@ -86,3 +110,45 @@ distribution directs syslog's 'daemon' facility output, as
enormously. See the logging section of file
contrib/fedora/rpm/NetworkManager.conf for how to enable debug logging
in NetworkManager.
+
+
+Documentation
+-------------
+
+Updated documentation can be found at https://networkmanager.dev/docs
+
+Users can consult the man pages. Most relevant pages for normal users are:
+- NetworkManager daemon: [`NetworkManager (8)`][3], [`NetworkManager.conf (5)`][4]
+- nmcli: [`nmcli (1)`][5], [`nmcli-examples (5)`][6], [`nm-settings-nmcli (5)`][7]
+- nmtui: [`nmtui (1)`][8]
+
+
+Get in touch
+------------
+
+To connect with the community, get help or get involved see the available
+communication channels at https://networkmanager.dev/community/
+
+Report bugs or feature request in our [issue tracker](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues).
+See [Report issues](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/main/CONTRIBUTING.md?ref_type=heads#report-issues)
+for details about how to do it.
+
+To get involved, see [CONTRIBUTING.md](CONTRIBUTING.md)
+
+
+License
+-------
+
+NetworkManager is free software under GPL-2.0-or-later and LGPL-2.1-or-later.
+See [CONTRIBUTING.md#legal](CONTRIBUTING.md#legal) and
+[RELICENSE.md](RELICENSE.md) for details.
+
+
+[1]: https://nmstate.io/
+[2]: https://linux-system-roles.github.io/network/
+[3]: https://networkmanager.dev/docs/api/latest/NetworkManager.html
+[4]: https://networkmanager.dev/docs/api/latest/NetworkManager.conf.html
+[5]: https://networkmanager.dev/docs/api/latest/nmcli.html
+[6]: https://networkmanager.dev/docs/api/latest/nmcli-examples.html
+[7]: https://networkmanager.dev/docs/api/latest/nm-settings-nmcli.html
+[8]: https://networkmanager.dev/docs/api/latest/nmtui.html
diff --git a/contrib/scripts/anonymize-logs.py b/contrib/scripts/anonymize-logs.py
new file mode 100755
index 0000000000..36b82ed147
--- /dev/null
+++ b/contrib/scripts/anonymize-logs.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python3
+
+from textwrap import wrap
+import subprocess
+import ipaddress
+import argparse
+import os
+import re
+
+
+domains = []
+
+hosts_sub = {}
+host_next = 0
+
+macs_sub = {}
+mac_next = 0
+
+ips_sub = {}
+ip4_next = ipaddress.IPv4Address("0.0.0.0")
+ip6_next = ipaddress.IPv6Address("ffff::")
+
+
+def main(args):
+ must_autoreplace_hostnames = not args.show_hostnames
+ must_replace_hostnames = must_autoreplace_hostnames or args.domain or args.hostname
+
+ init_hostnames_and_domains_sub(args)
+
+ with open(args.log_file) as f:
+ for line in (line.strip() for line in f):
+ if must_replace_hostnames:
+ line = replace_hostnames(line, must_autoreplace_hostnames)
+ if not args.show_macs:
+ line = replace_macs(line)
+ if not args.show_public_ips or args.hide_private_ips:
+ line = replace_ips(line, args.show_public_ips, args.hide_private_ips)
+
+ print(line)
+
+
+def init_hostnames_and_domains_sub(args):
+ global domains
+
+ if not args.show_hostnames:
+ domains.extend(["com", "org", "net", "gov", "es", "it"])
+
+ r = subprocess.run("hostname", capture_output=True)
+ if r.returncode == 0:
+ own_hostname = r.stdout.decode().strip()
+ add_host_sub(own_hostname, ".self")
+
+ # domains and hostname passed explicitly are replaced even with --show-hostnames
+ domains.extend(d.strip(". ") for d in args.domain)
+ domains = "|".join(domains)
+
+ for hostname in args.hostname:
+ add_host_sub(hostname)
+
+
+def add_host_sub(hostname: str, suffix: str = ""):
+ global hosts_sub
+ global host_next
+
+ # if it's a domain-like hostname (i.e example.com) adds .ext at the end
+ if suffix == "" and re.search(r"\.({})$".format(domains), hostname):
+ suffix = ".ext"
+
+ if hostname not in hosts_sub:
+ hosts_sub[hostname] = "hostname{}{}".format(host_next, suffix)
+ host_next += 1
+
+
+def replace_hostnames(line: str, autodetect_from_logs: bool) -> str:
+ global hosts_sub
+
+ # look for known log messages that show hostnames
+ if autodetect_from_logs:
+ match = re.search(r"get-hostname: \"(.*)\"", line)
+ if match:
+ add_host_sub(match.group(1))
+
+ match = re.search(r"set hostname to \"(.*)\"", line)
+ if match:
+ add_host_sub(match.group(1))
+
+ match = re.search(
+ r"hostname changed from (\(none\)|\".*\") to (\(none\)|\".*\")", line
+ )
+ if match:
+ if match.group(1) != "(none)":
+ add_host_sub(match.group(1).strip('"'))
+ if match.group(2) != "(none)":
+ add_host_sub(match.group(2).strip('"'))
+
+ # look for domain-like strings
+ if domains:
+ match = re.search(r"[\w\-\.]+?\.(" + domains + r")\b", line)
+ if match:
+ add_host_sub(match.group(0))
+
+ for orig, repl in hosts_sub.items():
+ line = line.replace(orig, repl)
+
+ return line
+
+
+def replace_macs(line: str) -> str:
+ global macs_sub
+ global mac_next
+
+ macs = re.findall(r"(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}", line)
+
+ for mac in macs:
+ if mac not in macs_sub:
+ macs_sub[mac] = ":".join(wrap("{:012x}".format(mac_next), width=2))
+ mac_next += 1
+
+ line = line.replace(mac, macs_sub[mac])
+
+ return line
+
+
+def replace_ips(line: str, show_public: bool, hide_private: bool) -> str:
+ global ips_sub
+ global ip4_next
+ global ip6_next
+
+ ips4 = re.findall(r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}", line)
+ ips6 = re.findall(r"(?:[0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}", line)
+
+ for addr_str in ips4 + ips6:
+ try:
+ addr = ipaddress.ip_address(addr_str)
+ except: # not IP
+ continue
+
+ if (addr.is_private and not hide_private) or (addr.is_global and show_public):
+ continue
+
+ if addr.exploded not in ips_sub:
+ if type(addr) is ipaddress.IPv4Address:
+ ips_sub[addr.exploded] = str(ip4_next).replace("0.", "IP4.", 1)
+ ip4_next += 1
+ else:
+ ips_sub[addr.exploded] = str(ip6_next).replace("ffff:", "IPv6:", 1)
+ ip6_next += 1
+
+ line = line.replace(addr_str, ips_sub[addr.exploded])
+
+ return line
+
+
+if __name__ == "__main__":
+ args_parser = argparse.ArgumentParser(
+ prog=os.path.basename(__file__),
+ description="""Anonymize some data from NetworkManager logs.
+
+Note that it only covers some common stuff like MAC and IP addresses or
+hostnames. Do not trust it and manually review that the log doesn't contain
+sensitive data before sharing it.
+
+Changing IP address can make that problems related to routing are impossible to
+analyze. Because of that, private IPs which are normally not sensitive are not
+hidden by default, and if the problem is related to routing you might need to
+use the --show-public-ips option""",
+ epilog="Options of the type --show-* disable masking that type of data.",
+ formatter_class=argparse.RawTextHelpFormatter,
+ )
+ args_parser.add_argument("-H", "--show-hostnames", action="store_true")
+ args_parser.add_argument("-m", "--show-macs", action="store_true")
+ args_parser.add_argument("-g", "--show-public-ips", action="store_true")
+ args_parser.add_argument("-p", "--hide-private-ips", action="store_true")
+ args_parser.add_argument(
+ "-d",
+ "--domain",
+ action="append",
+ default=[],
+ help='additional domains to hide, like ".xyz", can be passed more than once',
+ )
+ args_parser.add_argument(
+ "-n",
+ "--hostname",
+ action="append",
+ default=[],
+ help="additional hostnames to hide, can be passed more than once",
+ )
+ args_parser.add_argument(
+ "log_file", nargs="?", default="/dev/stdin", help="Log file (by default, stdin)"
+ )
+
+ args = args_parser.parse_args()
+ main(args)
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 5403c46bd9..b331beb9dc 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -648,7 +648,9 @@ level=TRACE
domains=ALL
and restart the daemon with systemctl restart NetworkManager. Then
- reproduce the problem. You can find the logs in syslog (for example journalctl).
+ reproduce the problem. You can find the logs in syslog (for example
+ journalctl, or journalctl -u NetworkManager
+ to show only logs from NetworkManager).