summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-09-22 20:32:14 +0200
committerThomas Haller <thaller@redhat.com>2021-06-08 12:52:39 +0200
commit8b2905fcce86ed2bfa7214676d7a945098a1ba82 (patch)
tree6138021b2a2d12ed9e6a502725778bdb510069bd
parent5c1181c6f3b2f56c18c1333c55e75e554b00ae2d (diff)
downloadNetworkManager-th/l3cfg-20.tar.gz
core: use NML3ConfigData (WIP)th/l3cfg-20
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am20
-rw-r--r--WIP.txt13
-rw-r--r--src/core/README.l3cfg.md332
-rw-r--r--src/core/devices/adsl/nm-device-adsl.c52
-rw-r--r--src/core/devices/bluetooth/nm-device-bt.c27
-rw-r--r--src/core/devices/nm-acd-manager.c496
-rw-r--r--src/core/devices/nm-acd-manager.h34
-rw-r--r--src/core/devices/nm-device-bond.c1
-rw-r--r--src/core/devices/nm-device-dummy.c1
-rw-r--r--src/core/devices/nm-device-ethernet.c40
-rw-r--r--src/core/devices/nm-device-infiniband.c1
-rw-r--r--src/core/devices/nm-device-ip-tunnel.c1
-rw-r--r--src/core/devices/nm-device-macvlan.c1
-rw-r--r--src/core/devices/nm-device-ppp.c69
-rw-r--r--src/core/devices/nm-device-private.h16
-rw-r--r--src/core/devices/nm-device-tun.c1
-rw-r--r--src/core/devices/nm-device-vlan.c2
-rw-r--r--src/core/devices/nm-device-vxlan.c1
-rw-r--r--src/core/devices/nm-device-wireguard.c74
-rw-r--r--src/core/devices/nm-device-wpan.c1
-rw-r--r--src/core/devices/nm-device.c5053
-rw-r--r--src/core/devices/nm-device.h23
-rw-r--r--src/core/devices/ovs/nm-device-ovs-bridge.c8
-rw-r--r--src/core/devices/ovs/nm-device-ovs-interface.c10
-rw-r--r--src/core/devices/ovs/nm-device-ovs-port.c8
-rw-r--r--src/core/devices/team/nm-device-team.c1
-rw-r--r--src/core/devices/tests/meson.build1
-rw-r--r--src/core/devices/tests/test-acd.c259
-rw-r--r--src/core/devices/wifi/nm-device-wifi-p2p.c11
-rw-r--r--src/core/devices/wifi/nm-device-wifi.c11
-rw-r--r--src/core/devices/wwan/nm-device-modem.c105
-rw-r--r--src/core/devices/wwan/nm-modem-broadband.c258
-rw-r--r--src/core/devices/wwan/nm-modem-ofono.c120
-rw-r--r--src/core/devices/wwan/nm-modem.c377
-rw-r--r--src/core/devices/wwan/nm-modem.h42
-rw-r--r--src/core/dhcp/nm-dhcp-client.c199
-rw-r--r--src/core/dhcp/nm-dhcp-client.h17
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient-utils.c1
-rw-r--r--src/core/dhcp/nm-dhcp-manager.c32
-rw-r--r--src/core/dhcp/nm-dhcp-manager.h5
-rw-r--r--src/core/dhcp/nm-dhcp-nettools.c243
-rw-r--r--src/core/dhcp/nm-dhcp-systemd.c267
-rw-r--r--src/core/dhcp/nm-dhcp-utils.c306
-rw-r--r--src/core/dhcp/nm-dhcp-utils.h31
-rw-r--r--src/core/dhcp/tests/test-dhcp-dhclient.c1
-rw-r--r--src/core/dhcp/tests/test-dhcp-utils.c567
-rw-r--r--src/core/dns/nm-dns-dnsmasq.c33
-rw-r--r--src/core/dns/nm-dns-manager.c539
-rw-r--r--src/core/dns/nm-dns-manager.h18
-rw-r--r--src/core/dns/nm-dns-systemd-resolved.c64
-rw-r--r--src/core/dnsmasq/nm-dnsmasq-manager.c51
-rw-r--r--src/core/dnsmasq/nm-dnsmasq-manager.h10
-rw-r--r--src/core/meson.build4
-rw-r--r--src/core/ndisc/nm-ndisc.c102
-rw-r--r--src/core/ndisc/nm-ndisc.h7
-rw-r--r--src/core/nm-act-request.c38
-rw-r--r--src/core/nm-act-request.h8
-rw-r--r--src/core/nm-connectivity.c1
-rw-r--r--src/core/nm-dhcp-config.c58
-rw-r--r--src/core/nm-dhcp-config.h2
-rw-r--r--src/core/nm-dispatcher.c178
-rw-r--r--src/core/nm-dispatcher.h8
-rw-r--r--src/core/nm-iface-helper.c22
-rw-r--r--src/core/nm-ip-config.c459
-rw-r--r--src/core/nm-ip-config.h45
-rw-r--r--src/core/nm-ip4-config.c3297
-rw-r--r--src/core/nm-ip4-config.h667
-rw-r--r--src/core/nm-ip6-config.c2711
-rw-r--r--src/core/nm-ip6-config.h208
-rw-r--r--src/core/nm-manager.c2
-rw-r--r--src/core/nm-pacrunner-manager.c94
-rw-r--r--src/core/nm-pacrunner-manager.h7
-rw-r--r--src/core/nm-policy.c319
-rw-r--r--src/core/nm-proxy-config.c172
-rw-r--r--src/core/nm-proxy-config.h41
-rw-r--r--src/core/nm-types.h3
-rw-r--r--src/core/ppp/nm-ppp-manager-call.c18
-rw-r--r--src/core/ppp/nm-ppp-manager-call.h6
-rw-r--r--src/core/ppp/nm-ppp-manager.c171
-rw-r--r--src/core/ppp/nm-ppp-manager.h3
-rw-r--r--src/core/ppp/nm-ppp-plugin-api.h6
-rw-r--r--src/core/tests/test-ip4-config.c1
-rw-r--r--src/core/tests/test-ip6-config.c2
-rw-r--r--src/core/vpn/nm-vpn-connection.c709
-rw-r--r--src/core/vpn/nm-vpn-connection.h4
-rw-r--r--src/libnm-systemd-core/meson.build2
-rw-r--r--src/libnm-systemd-core/nm-sd.h1
-rwxr-xr-xtools/run-nm-test.sh1
89 files changed, 5112 insertions, 14121 deletions
diff --git a/.gitignore b/.gitignore
index 22f745efe9..da3032c3d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -233,7 +233,6 @@ test-*.trs
/src/core/NetworkManager-all-sym
/src/core/NetworkManager.ver
/src/core/devices/bluetooth/tests/nm-bt-test
-/src/core/devices/tests/test-acd
/src/core/devices/tests/test-lldp
/src/core/devices/wifi/tests/test-devices-wifi
/src/core/devices/wwan/tests/test-service-providers
@@ -399,6 +398,7 @@ test-*.trs
/src/NetworkManager
/src/NetworkManager-all-sym
/src/NetworkManager.ver
+/src/core/devices/tests/test-acd
/src/core/initrd/nm-initrd-generator
/src/core/initrd/tests/test-cmdline-reader
/src/core/initrd/tests/test-dt-reader
diff --git a/Makefile.am b/Makefile.am
index dbcd9816e7..eeffa46a98 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2309,8 +2309,6 @@ src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp-lease.c \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-lease.c \
- src/libnm-systemd-core/src/libsystemd-network/sd-ipv4acd.c \
- src/libnm-systemd-core/src/libsystemd-network/sd-ipv4ll.c \
src/libnm-systemd-core/src/libsystemd-network/sd-lldp.c \
src/libnm-systemd-core/src/libsystemd/sd-event/event-source.h \
src/libnm-systemd-core/src/libsystemd/sd-event/event-util.c \
@@ -2328,8 +2326,6 @@ src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
src/libnm-systemd-core/src/systemd/sd-dhcp6-option.h \
src/libnm-systemd-core/src/systemd/sd-event.h \
src/libnm-systemd-core/src/systemd/sd-id128.h \
- src/libnm-systemd-core/src/systemd/sd-ipv4acd.h \
- src/libnm-systemd-core/src/systemd/sd-ipv4ll.h \
src/libnm-systemd-core/src/systemd/sd-lldp.h \
src/libnm-systemd-core/src/systemd/sd-ndisc.h \
$(NULL)
@@ -2377,10 +2373,6 @@ src_core_libNetworkManagerBase_la_SOURCES = \
src/core/nm-l3cfg.h \
src/core/nm-ip-config.c \
src/core/nm-ip-config.h \
- src/core/nm-ip4-config.c \
- src/core/nm-ip4-config.h \
- src/core/nm-ip6-config.c \
- src/core/nm-ip6-config.h \
\
src/core/dhcp/nm-dhcp-client.c \
src/core/dhcp/nm-dhcp-client.h \
@@ -2419,8 +2411,6 @@ src_core_libNetworkManager_la_SOURCES = \
src/core/nm-checkpoint-manager.c \
src/core/nm-checkpoint-manager.h \
\
- src/core/devices/nm-acd-manager.c \
- src/core/devices/nm-acd-manager.h \
src/core/devices/nm-lldp-listener.c \
src/core/devices/nm-lldp-listener.h \
src/core/devices/nm-device-utils.c \
@@ -2569,8 +2559,6 @@ src_core_libNetworkManager_la_SOURCES = \
src/core/nm-firewall-utils.h \
src/core/nm-firewalld-manager.c \
src/core/nm-firewalld-manager.h \
- src/core/nm-proxy-config.c \
- src/core/nm-proxy-config.h \
src/core/nm-auth-manager.c \
src/core/nm-auth-manager.h \
src/core/nm-auth-utils.c \
@@ -4254,20 +4242,14 @@ src_core_devices_tests_ldflags = \
check_programs += \
src/core/devices/tests/test-lldp \
- src/core/devices/tests/test-acd
+ $(NULL)
src_core_devices_tests_test_lldp_CPPFLAGS = $(src_core_cppflags_test)
src_core_devices_tests_test_lldp_LDFLAGS = $(src_core_devices_tests_ldflags)
src_core_devices_tests_test_lldp_LDADD = \
src/core/libNetworkManagerTest.la
-src_core_devices_tests_test_acd_CPPFLAGS = $(src_core_cppflags_test)
-src_core_devices_tests_test_acd_LDFLAGS = $(src_core_devices_tests_ldflags)
-src_core_devices_tests_test_acd_LDADD = \
- src/core/libNetworkManagerTest.la
-
$(src_core_devices_tests_test_lldp_OBJECTS): $(src_libnm_core_public_mkenums_h)
-$(src_core_devices_tests_test_acd_OBJECTS): $(src_libnm_core_public_mkenums_h)
EXTRA_DIST += \
src/core/devices/tests/meson.build
diff --git a/WIP.txt b/WIP.txt
new file mode 100644
index 0000000000..688cb6785f
--- /dev/null
+++ b/WIP.txt
@@ -0,0 +1,13 @@
+The following files have changes since the last rebase,
+that need re-review. They probably also don't compile
+and are incomplete:
+
+ > src/core/devices/nm-device.c
+ > src/core/devices/nm-device.h
+ > src/core/nm-iface-helper.c
+ > src/core/nm-ip-config.c
+ > src/core/nm-ip4-config.h
+ > src/core/nm-ip6-config.h
+ > src/core/nm-manager.c
+ > src/core/nm-policy.c
+ > src/core/vpn/nm-vpn-connection.c
diff --git a/src/core/README.l3cfg.md b/src/core/README.l3cfg.md
new file mode 100644
index 0000000000..100ce012ea
--- /dev/null
+++ b/src/core/README.l3cfg.md
@@ -0,0 +1,332 @@
+L3Cfg Rework
+============
+
+NMDevice is complex. Together with NMManager, NMDevice does too much.
+
+The goal is to rework the IP configuration (Layer 3) to be a more separate
+part of the code that is better maintainable, easier to understand and
+extend and more correct.
+
+Current Situation
+-----------------
+
+- [NMManager](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-manager.c):
+ this is the main object (a singleton) that drives most things.
+ Among many other things, it creates NMDevice instances and coordinates.
+
+- [NMDevice](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c):
+ this represents a device. This is a subclass of NMDBusObject,
+ it is thus directly exported on D-Bus (as D-Bus objects like
+ `/org/freedesktop/NetworkManager/Devices/1`).
+ It also manages all aspects of the device. It has an overall state
+ (`NM_DEVICE_STATE`) but lots of more specific states (e.g. current state
+ of DHCP configuration). As always, the hardest part in programming are
+ stateful objects, and NMDevice has *a lot* of state. The code is huge and
+ hard to understand and the class has (too) many responsibilities. \
+ \
+ NMDevice also has subclasses, which are determined based on the "device type". That
+ means, there are subclasses like NMDeviceEthernet and NMDeviceBridge. As such, the
+ subclasses also export additional D-Bus interfaces. These subclasses also handle
+ the Layer 2 specific aspects of the device. For this aspect, delegation probably
+ would have been a better choice. On the other hand, IP configuration is almost entirely
+ managed by the parent class. Which is good, because the IP configuration is common to all
+ device types, but is bad because NMDevice already does so many things.
+
+- [NMIP4Config](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-ip4-config.c) (and NMIP6Config):
+ these are also subclasses of NMDBusObject
+ and exported on D-Bus on paths like `/org/freedesktop/NetworkManager/IP4Config/1`.
+ The device's `IP4Config` property refers to these objects. They contain
+ the runtime IP information of that device. I don't think these objects
+ should exist on the D-Bus API, as NMDevice could directly expose these properties.
+ But for historic reasons, such is our D-Bus API.
+ Other than that, NMIP4Config objects are also used internally for tracking
+ IP configuration. For example, [when](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/dhcp/nm-dhcp-nettools.c#L563)
+ we receive a DHCP lease, we construct a NMIP4Config object with the addresses, DNS settings,
+ and so on. These
+ instances are then [tracked by](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L519)
+ NMDevice, and [merged](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L8928)
+ into an instance that is then exposed on D-Bus. As such, this class has two
+ mostly independent purposes.
+
+- [NMDhcpClient](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/dhcp/nm-dhcp-client.c):
+ our DHCP "library". It's a simple object with a clear API that
+ abstracts most of the complexity of handling DHCP. But still, NMDevice
+ needs to drive the DHCP client instance. Meaning, it needs to create (start) and stop
+ them and hook up signals for changes (new lease) and timeout. This is mostly
+ fine and unavoidable. The point is that while specific tasks are well abstracted
+ (like the details of DHCP), there is still some state in NMDevice that is related
+ to manage these tasks. DHCP is one of many such tasks, like also
+ link local addresses, SLAAC or LLDP.
+ This leads to the increased complexity of NMDevice, which manages a large variety
+ of such tasks.
+
+### Problems:
+
+1. first the sheer code size of [nm-device.c](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L19030).
+ It's hard to understand and maintain, and this results in misbehaviours. Also, features that should be easy to implement
+ are not. Also, there are inefficiencies that are hard to fix.
+
+2. NMDevice and NMIP4Config are both exported on D-Bus while having other responsibilities.
+ Being subclasses of NMDBusObject, they are glued to the D-Bus API. For example, NMIP4Config is
+ also used for other purposes (for tracking IP configuration internally).
+
+3. NMDevice simply does too much. IP configuration should be a separate, encapsulated
+ API to make allow NMDevice to be smaller and the IP configuration part better
+ testable, understandable and smaller too.
+
+4. in the current model, NMDevice can be related to zero, one or two ifindexes. For example,
+ for ethernet devices, there is commonly only one actual netdev device (and one ifindex).
+ For OVS devices, there is no ifindex. For NMDeviceModem or NMDeviceBluetooth there is
+ a NMDevice instance that has initially no ifindex (it represents the tty serial port
+ or the bluetooth device) but during activation it gets and ip ifindex. With PPPoE,
+ the ethernet device can even have two ifindexes (one for the underlying ethernet and
+ one for the PPP device). That is all utterly confusing, inconsistent and limited.
+ For example, not all interfaces you see in `ip link` can be found in the D-Bus API.
+ The D-Bus API also does not give access to the ifindex (which is the real identifier
+ for a netdev devices). It only exposes the IpInterface name. That should be improved too,
+ but even such seemingly simple things are not done for years, because it's not trivially
+ clear what the right ifindex is.
+ Also a device instance on D-Bus significantly changes its meaning when it activates/deactivates
+ and it starts/stops being responsible for an ifindex.
+ In the future there should be devices that represent exactly one netdev device (an ifindex)
+ and devices that don't have an ifindex. That is follow up work and hinted by
+ [rhbz#1066703](https://bugzilla.redhat.com/show_bug.cgi?id=1066703). But simplifying
+ the IP configuration is a requisite before addressing that rework.
+ With this we will have controller and controlled devices. That means, a controller devices
+ (that for example represents a bluetooth device) will need to configure IP address on the
+ controlled IP device. That would be doable by injecting the IP config on that device,
+ but as the device already does so much, it would be better if this would be a separate
+ IP configuration manager for that ifindex.
+
+5. NMIP4Config exports properties on D-Bus like [AddressData](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/introspection/org.freedesktop.NetworkManager.IP4Config.xml#L26).
+ which are the currently configured IP addresses. These should be directly obtained
+ from the NMPlatform cache, which contains the correct list of addresses as kernel
+ exposes them via rtnetlink. Instead, whenever there are changes in platform we
+ [generate](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L14223)
+ an NMIP4Config instance, then we merge, intersect and subtract this captured information
+ with the IP configs we want to configure. Finally we merge them together again
+ and sync the result to platform. This is bad, wrong and inefficient.
+ We must not mix "what is configured" with "what we want to configure". The current
+ approach also re-generates these IP config instance whenever something in platform changes.
+ That does not scale. If we have any hope to handle thousands of routes, this needs to change.
+
+6. The NMIP4Config objects are mutable, and they are heavily mutated. When we create an NMIP4Config
+ instance that represent a DHCP lease, we will [subtract](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L14236)
+ addresses that were externally removed. That is wrong, because during a reapply we
+ will need to know these addresses again. The solution for that is not to mutate this
+ data, but track whether IP addresses are removed separately.
+
+7. NMDevice also does ACD, but it can only do it for addresses received via DHCP.
+ It implicitly also does ACD for IPv4LL, but that is via using the n_ipv4ll library.
+ It would be good to have an option that we can configure IPv4LL for any address.
+ Also, if you manually configure an address like 192.168.2.5 (for which we don't do
+ ACD) and the same address is obtained via DHCP, then doing ACD for the address is wrong.
+ There needs to be link-wide view of the addresses, and not only looking at individual
+ addresses when deciding to do ACD.
+
+8. As IP configuration is done by NMDevice, VPN connections have limited capabilities
+ in this regard.
+ When a VPN has IP addresses, then it injects them into NMDevice by
+ [providing](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L13696)
+ an NMIP4Config. However, that means VPNs cannot do DHCP or IPv4LL, because it can
+ only inject known configuration. That would be very useful for example with a tap
+ device with openvpn. The real problem here is that NMVpnConnection are
+ treated special, when they should be more like devices. That should be reworked in the future,
+ by reworking VPN plugins. Regardless, having IP configuration handled by NMDevice is limiting.
+
+9. NetworkManager currently supports `ipv4.method` which can be "manual", "disabled" or
+ "auto". This scheme does not allow for example to enable IPv4LL together with DHCPv4.
+ As a special case, you can configure `ipv4.method=auto` together with static
+ addresses in `ipv4.addresses`, so combining DHCP and static addressing works. But in general,
+ this scheme is limited. In the future we should have more flexible schemes, where
+ addressing methods can be independently enabled or disabled. Also, we currently
+ have `ipv4.may-fail`, but that is limited as well. For example,
+ `ipv4.may-fail=yes` and `ipv6.may-fail=yes` still means that at least one of the
+ address families must succeed. That makes sense for certain use cases, but it
+ means, you cannot have truly best-effort, opportunistic DHCP with this way.
+ As workaround for that there is `ipv4.dhcp-timeout=infinity`. In
+ general it is not only useful to enable methods independently, we also configure
+ independently whether they are required or optional (and possibly, that they are optional
+ but at least one of several optional methods must succeed). Anyway. The point
+ is there is a need to make IP configuration more flexible. Currently it is not.
+ Such a seemingly simple extension would be surprisingly difficult to implement
+ because [the code](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L6616) is
+ all over the place. The way how NMDevice tracks the overall activation state is
+ hard to understand. This should be improved and possibly could be improved in a
+ smaller refactoring effort. But instead of a smaller effort, we will use the big hammer
+ with L3Cfg rework.
+
+10. There are two classes NMIP4Config and NMIP6Config. Handling both address families is
+ commonly similar, so there is lot of similar code in both. They should be unified
+ so that similar code can handle both address families.
+
+
+Solution and Future
+-------------------
+
+NML3Cfg work is supposed to simplify some part of NMDevice: the part related to
+IP configuration. This is a huge rework of a core part of NetworkManager. Arguably,
+some parts maybe could be done more evolutionary, but the fundamental problems require
+to rip out NMIP4Config and replace it by something better. Doing that is a large rework
+that changes NMDevice heavily. That is also the opportunity to get the smaller issues
+right.
+
+There is already a new class [NML3Cfg](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.h#L141)
+(currently unused). An NML3Cfg instance is responsible for handling IP configuration
+of an ifindex. Consequently, we can ask NMNetns to [get](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-netns.c#L142)
+(or create) a NML3Cfg instance for an ifindex.
+The idea is that there can be multiple users (NMDevice and NMVpnConnection and future controller devices)
+that use the same NML3Cfg instance. Especially with a future rework of NMDevice where
+a NMDevice only manages one ifindex (or none), there is a need that multiple
+devices manage the IP configuration on the same device. Independent users can cooperate
+to configure IP configuration on the same device. Already now with Libreswan VPN, where the VPN "injects"
+its NMIP4Config in NMDevice. Or with PPPoE, where the NMDeviceEthernet is both about IP configuration
+for the PPPoE device.
+
+There is also a new class [NML3ConfigData](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3-config-data.h).
+This replaces some aspect of NMIP4Config/NMIP6Config. A NML3ConfigData object is immutable and has no real logic
+(or state). It has some "logic", like comparing two NML3ConfigData instances, logging it, or merging two (immutable)
+instances into a new instance. But as the class is immutable, that logic is rather simple. This class is
+used to track information. As it's immutable, anybody who is interested can keep a reference
+for it's own purpose. For example, NMDhcpClient will generate a NML3ConfigData with the information
+of the lease. It may keep the reference, but it will also tell NMDevice about it. The NMDevice
+will then itself tell NML3Cfg to accept this configuration. This works by calling
+[add()/remove()](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L2654).
+One NML3ConfigData can also track both IPv4 and IPv6 information. It's a general set of IP related
+configuration, that has some address specific properties. Those are then duplicated for both address
+families and implemented in a way to minimize code duplication and encourage to treat them the same.
+As this replaces an aspect of NMIP4Config, NMIP4Config can focus on it's other purpose: to expose data on D-Bus.
+
+What NML3Cfg then does, is to merge all NML3ConfigData, and "commit" it to platform. Thereby it knows
+which addresses it configured the last time (if they no longer are to be configured, they must be removed).
+This is done [here](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L3442).
+
+As independent users should be able to cooperate, it is not appropriate that they call "commit".
+Instead, they set a commit type ([here](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L3476),
+and whenever something changes, NML3Cfg knows the aggregated commit type. That is necessary
+because when we activate a device, we may want to preserve the existing IP configuration (e.g. after
+a restart of NetworkManager). During that time is the NML3Cfg instance set to a reduced commit
+mode (ASSUME).
+
+NML3Cfg will also handle IPv4 ACD. Any user of NML3Cfg registers/unregisters NML3ConfigData instances
+that should be configured. Thereby they also say whether ACD should be done for the IPv4 addresses.
+NML3Cfg then keeps state for each IPv4 address, whether ACD should be performed, and whether the
+address is ready to be configured. NML3Cfg does not do DHCP or similar. That is still the responsibility
+of NMDevice to run a NMDhcpClient. But it does run ACD, because whether to perform ACD on an address
+requires a holistic view of all addresses of that interface. For example, if you configure a static
+IP address 192.168.2.5 (with ACD disabled) and you also get the same address via DHCP, then ACD should
+not performed for that address (even if the user configured ACD with DHCP). Of course, that is a very
+unlikely example. More likely is that NetworkManager is restarted and it leaves the addresses (that passed
+ACD) configured. After restart, DHCP finds the same addresses and no new ACD should be performed. This shows
+that the ACD state depends all the IP addresses on an interface,
+and thus it's done by NML3Cfg. The API for this is very simple. Users enable/disable ACD during nm_l3cfg_add_config()
+and receive events like [NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L303).
+Another advantage is that ACD now works for any kinds of addresses. Currently it only works for addresses
+from DHCP and link local addresses.
+
+NML3Cfg does not implement or drive DHCP. However, as it already does ACD it gained it's own IPv4LL
+"library": [NML3IPv4LL](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L3624).
+This will replace nettools' n-ipv4ll library, because that library also does ACD internally, while we want
+to use the holistic view that NML3Cfg has. What this means, is that the user (NMDevice)
+can request a NML3IPv4LL handle from the NML3Cfg instance, and it just does it with a simple API.
+All the user might do is to enable/disable the handle and to react to signals (if it cares to find
+out whether IPv4LL fails).
+
+The general parts of NML3Cfg are already implemented. It has unit tests and can be tested independently.
+You might note that NML3Cfg is not trivial already, but the API that it provides is as simple as possible:
+create immutable NML3ConfigData instance, and add/remove them. Optionally, handle the ACD events and
+listen to some events. The complexity that NML3Cfg has, will lead in the same amount simplify NMDevice.
+
+What is missing is NMDevice using this new API. Instead of creating and tracking NMIP4Config instances,
+it needs to track NML3ConfigData instances. In principle that sounds simple, in practice that changes
+large part of "nm-device.c".
+
+Thereby also the state machine for NM_DEVICE_STATE will be improved. It's anyway a rewrite. This will lay the
+groundwork for more flexible configuration of IP methods, with different failure modes (opportunistic or
+mandatory).
+
+What then also should be easier, to combine IPv4LL with other addressing methods. In Windows AFAIK, if you
+don't get a DHCP address it will configure a IPv4LL address. That is also what RFC suggests, but which we
+currently don't support.
+
+In general, change the way how external IP addresses/routes are tracked. This merge, intersect, subtract
+approach does not perform well. Currently we react on signals and it's hard to understand what happens
+in response to that, or whether it's really the correct thing to do. See yourself starting from
+[here](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/devices/nm-device.c#L14214).
+
+### DHCP
+
+Currently, when NMDhcpClient receives a lease, it emits a signal with two things: the NMIP4Config
+instance (containing addresses, routes, DNS settings and other information for later use), and a string
+dictionary with the DHCP lease options (they are mainly used to expose them on D-Bus). The latter is
+immutable (meaning, it's not changed afterwards). That does not significantly change with L3Cfg. The
+difference is that instead of NMIP4Config a NML3ConfigData instance gets created. That instance then
+references the (immutable) strdict. With that, any part of the code that has access to the NML3ConfigData,
+also has access to the lease options. So instead of two separate
+pieces of information, the result of a lease event will only be a NML3ConfigData instance (which internally
+tracks the strdict with the DHCP lease options).
+
+Later, when NML3Cfg configures an interface, it takes all NML3ConfigData instances that were added to
+it, and merges them. [Currently](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3-config-data.c#L2693),
+the merged data will not contain the lease information, but it's probably not needed anyway.
+
+If it would be needed, the question is what happens if multiple lease informations are present
+during the merge. Duplicate leases would not commonly happen, but in general, the merging algorithm
+needs to take into account priorities and conflicting data.
+That is done by users who call [add](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L2658)
+to provide a priority for the NML3ConfigData instance.
+Later, the instances get sorted by priority and merging is smart to take that into account
+([here](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/nm-l3cfg.c#L2983)).
+
+Also, we currently inject the route-metric and table into the generated NMIP4Config.
+Those settings come from the connection profiles and not from DHCP. We will avoid that
+by allowing the routes in NML3ConfigData to be marked as metric\_any and table\_any.
+That way,the NML3ConfigData is independent (and immutable) with respect to those settings.
+The same happens for example with PPP, where the modem starts PPP, and currently the
+route and metric needs to be passed several layers down. But worst, those settings
+can change during reapply. Currently that means we need to hack NMIP4Config with
+those changes. Later, we will only tell NML3Cfg to track the NML3ConfigData with
+different settings.
+
+### DNS
+
+DNS information is currently set in the NMIP4Config instances. That happens for example with the DNS information
+from a DHCP lease, but also with the static DNS settings from the connection profile. Later, the same information
+will packed in NML3ConfigData.
+
+One nice difference is again the immutability. Currently, NMDnsManager keeps a reference to all relevant NMIP4Config instances,
+but as they are mutable, it needs to [subscribe](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/6b64fac06d2f6e0d9fa530ebb1ab28d53a1c5d03/src/core/dns/nm-dns-manager.c#L275)
+to changes. Later, when a NML3ConfigData instance "changes", it means it was
+replaced by a different one and NMDnsManager needs to update its list of tracked NML3ConfigData. I find that
+cleaner, because adding and removal to the list of NMIP4Config/NML3ConfigData happens anyway and needs to be handled.
+
+
+Related Bugs
+------------
+
+* Main bug:
+
+ - [rh#1868254](https://bugzilla.redhat.com/show_bug.cgi?id=1868254):
+ "refactor NetworkManager's IP configuration done by NMDevice"
+
+* Follow up but to improve model of devices:
+
+ - [rh#1066703](https://bugzilla.redhat.com/show_bug.cgi?id=1066703):
+ "\[RFE\] Handle parent/child relationships more cleanly"
+
+* Flexible IP methods:
+
+ - [rh#1791624](https://bugzilla.redhat.com/show_bug.cgi?id=1791624):
+ "NetworkManager must not remove used bridge"
+
+* Improving performance issues, this will lay ground work:
+
+ - [rh#1847125](https://bugzilla.redhat.com/show_bug.cgi?id=1847125):
+ "\[RFE\] Improve 20% performance on creating 1000 bridge over 1000 VLANs"
+
+ - [rh#1861527](https://bugzilla.redhat.com/show_bug.cgi?id=1861527):
+ "Excessive memory and CPU usage on a router with IPv6 BGP feed"
+
+ - [rh#1753677](https://bugzilla.redhat.com/show_bug.cgi?id=1753677):
+ "High cpu usage while non-controlled interface is mangling tc filters"
+
diff --git a/src/core/devices/adsl/nm-device-adsl.c b/src/core/devices/adsl/nm-device-adsl.c
index 4e4c9dcc9c..1909e98339 100644
--- a/src/core/devices/adsl/nm-device-adsl.c
+++ b/src/core/devices/adsl/nm-device-adsl.c
@@ -15,7 +15,6 @@
#include <unistd.h>
#include <stdlib.h>
-#include "nm-ip4-config.h"
#include "devices/nm-device-private.h"
#include "libnm-platform/nm-platform.h"
#include "ppp/nm-ppp-manager-call.h"
@@ -434,19 +433,30 @@ ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpoin
}
static void
-ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data)
+ppp_new_config(NMPPPManager * ppp_manager,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ const NMUtilsIPv6IfaceId *iid,
+ gpointer user_data)
{
NMDevice *device = NM_DEVICE(user_data);
- /* Ignore PPP IP4 events that come in after initial configuration */
- if (nm_device_activate_ip4_state_in_conf(device))
- nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config));
+ if (addr_family != AF_INET)
+ return;
+
+ if (!nm_device_activate_ip4_state_in_conf(device)) {
+ /* Ignore PPP events that come in after initial configuration */
+ return;
+ }
+
+ nm_device_set_dev2_ip_config(device, AF_INET, l3cd);
+ nm_device_activate_schedule_ip_config_result(device, AF_INET);
}
static NMActStageReturn
-act_stage3_ip4_config_start(NMDevice * device,
- NMIP4Config ** out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip4_config_start(NMDevice * device,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
NMDeviceAdsl * self = NM_DEVICE_ADSL(device);
NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self);
@@ -476,14 +486,6 @@ act_stage3_ip4_config_start(NMDevice * device,
priv->ppp_manager = nm_ppp_manager_create(ppp_iface, &err);
- if (priv->ppp_manager) {
- nm_ppp_manager_set_route_parameters(priv->ppp_manager,
- nm_device_get_route_table(device, AF_INET),
- nm_device_get_route_metric(device, AF_INET),
- nm_device_get_route_table(device, AF_INET6),
- nm_device_get_route_metric(device, AF_INET6));
- }
-
if (!priv->ppp_manager
|| !nm_ppp_manager_start(priv->ppp_manager,
req,
@@ -509,23 +511,23 @@ act_stage3_ip4_config_start(NMDevice * device,
G_CALLBACK(ppp_ifindex_set),
self);
g_signal_connect(priv->ppp_manager,
- NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
- G_CALLBACK(ppp_ip4_config),
+ NM_PPP_MANAGER_SIGNAL_NEW_CONFIG,
+ G_CALLBACK(ppp_new_config),
self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
if (addr_family == AF_INET)
- return act_stage3_ip4_config_start(device, (NMIP4Config **) out_config, out_failure_reason);
+ return act_stage3_ip4_config_start(device, out_l3cd, out_failure_reason);
return NM_DEVICE_CLASS(nm_device_adsl_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static void
@@ -537,7 +539,7 @@ adsl_cleanup(NMDeviceAdsl *self)
g_signal_handlers_disconnect_by_func(priv->ppp_manager,
G_CALLBACK(ppp_state_changed),
self);
- g_signal_handlers_disconnect_by_func(priv->ppp_manager, G_CALLBACK(ppp_ip4_config), self);
+ g_signal_handlers_disconnect_by_func(priv->ppp_manager, G_CALLBACK(ppp_new_config), self);
nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL);
g_clear_object(&priv->ppp_manager);
}
diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c
index 8f4ceba75e..67c1476c2e 100644
--- a/src/core/devices/bluetooth/nm-device-bt.c
+++ b/src/core/devices/bluetooth/nm-device-bt.c
@@ -25,7 +25,6 @@
#include "settings/nm-settings-connection.h"
#include "nm-utils.h"
#include "nm-bt-error.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "devices/wwan/nm-modem-manager.h"
@@ -550,11 +549,20 @@ device_state_changed(NMDevice * device,
}
static void
-modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data)
+modem_new_config(NMModem * modem,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ gboolean do_slaac,
+ const NMUtilsIPv6IfaceId *iid,
+ GError * error,
+ gpointer user_data)
{
NMDeviceBt *self = NM_DEVICE_BT(user_data);
NMDevice * device = NM_DEVICE(self);
+ if (addr_family != AF_INET)
+ return;
+
g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE);
if (error) {
@@ -565,7 +573,8 @@ modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpoi
return;
}
- nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config));
+ nm_device_set_dev2_ip_config(device, AF_INET, l3cd);
+ nm_device_activate_schedule_ip_config_result(device, AF_INET);
}
static void
@@ -690,7 +699,7 @@ modem_try_claim(NMDeviceBt *self, NMModem *modem)
g_signal_connect(modem, NM_MODEM_PPP_STATS, G_CALLBACK(ppp_stats), self);
g_signal_connect(modem, NM_MODEM_PPP_FAILED, G_CALLBACK(ppp_failed), self);
g_signal_connect(modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK(modem_prepare_result), self);
- g_signal_connect(modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK(modem_ip4_config_result), self);
+ g_signal_connect(modem, NM_MODEM_NEW_CONFIG, G_CALLBACK(modem_new_config), self);
g_signal_connect(modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK(modem_auth_requested), self);
g_signal_connect(modem, NM_MODEM_AUTH_RESULT, G_CALLBACK(modem_auth_result), self);
g_signal_connect(modem, NM_MODEM_STATE_CHANGED, G_CALLBACK(modem_state_cb), self);
@@ -1002,10 +1011,10 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device);
@@ -1023,7 +1032,7 @@ act_stage3_ip_config_start(NMDevice * device,
}
return NM_DEVICE_CLASS(nm_device_bt_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static void
diff --git a/src/core/devices/nm-acd-manager.c b/src/core/devices/nm-acd-manager.c
deleted file mode 100644
index 995abacded..0000000000
--- a/src/core/devices/nm-acd-manager.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2015 - 2018 Red Hat, Inc.
- */
-
-#include "src/core/nm-default-daemon.h"
-
-#include "nm-acd-manager.h"
-
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <linux/if_ether.h>
-
-#include "libnm-platform/nm-platform.h"
-#include "nm-utils.h"
-#include "NetworkManagerUtils.h"
-#include "n-acd/src/n-acd.h"
-
-/*****************************************************************************/
-
-typedef enum {
- STATE_INIT,
- STATE_PROBING,
- STATE_PROBE_DONE,
- STATE_ANNOUNCING,
-} State;
-
-typedef struct {
- in_addr_t address;
- gboolean duplicate;
- NAcdProbe *probe;
-} AddressInfo;
-
-struct _NMAcdManager {
- int ifindex;
- guint8 hwaddr[ETH_ALEN];
- State state;
- GHashTable *addresses;
- guint completed;
- NAcd * acd;
- GSource * event_source;
-
- NMAcdCallbacks callbacks;
- gpointer user_data;
-};
-
-/*****************************************************************************/
-
-#define _NMLOG_DOMAIN LOGD_IP4
-#define _NMLOG_PREFIX_NAME "acd"
-#define _NMLOG(level, ...) \
- G_STMT_START \
- { \
- char _sbuf[64]; \
- \
- nm_log((level), \
- _NMLOG_DOMAIN, \
- self && self->ifindex > 0 \
- ? nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex) \
- : NULL, \
- NULL, \
- "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
- _NMLOG_PREFIX_NAME, \
- self ? nm_sprintf_buf(_sbuf, "[%p,%d]", self, self->ifindex) \
- : "" _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
- } \
- G_STMT_END
-
-/*****************************************************************************/
-
-static const char *
-_acd_event_to_string(unsigned int event)
-{
- switch (event) {
- case N_ACD_EVENT_READY:
- return "ready";
- case N_ACD_EVENT_USED:
- return "used";
- case N_ACD_EVENT_DEFENDED:
- return "defended";
- case N_ACD_EVENT_CONFLICT:
- return "conflict";
- case N_ACD_EVENT_DOWN:
- return "down";
- }
- return NULL;
-}
-
-#define ACD_EVENT_TO_STRING_BUF_SIZE 50
-
-static const char *
-_acd_event_to_string_buf(unsigned event, char buffer[static ACD_EVENT_TO_STRING_BUF_SIZE])
-{
- const char *s;
-
- s = _acd_event_to_string(event);
- if (s)
- return s;
-
- g_snprintf(buffer, ACD_EVENT_TO_STRING_BUF_SIZE, "(%u)", event);
- return buffer;
-}
-
-static const char *
-acd_error_to_string(int error)
-{
- if (error < 0)
- return nm_strerror_native(-error);
-
- switch (error) {
- case _N_ACD_E_SUCCESS:
- return "success";
- case N_ACD_E_PREEMPTED:
- return "preempted";
- case N_ACD_E_INVALID_ARGUMENT:
- return "invalid argument";
- }
-
- g_return_val_if_reached(NULL);
-}
-
-static int
-acd_error_to_nmerr(int error, gboolean always_fail)
-{
- if (error < 0)
- return -nm_errno_native(error);
-
- if (always_fail) {
- if (NM_IN_SET(error, N_ACD_E_PREEMPTED, N_ACD_E_INVALID_ARGUMENT))
- return -NME_UNSPEC;
- g_return_val_if_reached(-NME_UNSPEC);
- }
-
- /* so, @error is either zero (indicating success) or one
- * of the special status codes like N_ACD_E_*. In both cases,
- * return the positive value here. */
- if (NM_IN_SET(error, _N_ACD_E_SUCCESS, N_ACD_E_PREEMPTED, N_ACD_E_INVALID_ARGUMENT))
- return error;
-
- g_return_val_if_reached(error);
-}
-
-/*****************************************************************************/
-
-/**
- * nm_acd_manager_add_address:
- * @self: a #NMAcdManager
- * @address: an IP address
- *
- * Add @address to the list of IP addresses to probe.
-
- * Returns: %TRUE on success, %FALSE if the address was already in the list
- */
-gboolean
-nm_acd_manager_add_address(NMAcdManager *self, in_addr_t address)
-{
- AddressInfo *info;
-
- g_return_val_if_fail(self, FALSE);
- g_return_val_if_fail(self->state == STATE_INIT, FALSE);
-
- if (g_hash_table_lookup(self->addresses, GUINT_TO_POINTER(address)))
- return FALSE;
-
- info = g_slice_new0(AddressInfo);
- info->address = address;
-
- g_hash_table_insert(self->addresses, GUINT_TO_POINTER(address), info);
-
- return TRUE;
-}
-
-static gboolean
-acd_event(int fd, GIOCondition condition, gpointer data)
-{
- NMAcdManager *self = data;
- NAcdEvent * event;
- AddressInfo * info;
- gboolean emit_probe_terminated = FALSE;
- char address_str[INET_ADDRSTRLEN];
- int r;
-
- if (n_acd_dispatch(self->acd))
- return G_SOURCE_CONTINUE;
-
- while (!n_acd_pop_event(self->acd, &event) && event) {
- char to_string_buffer[ACD_EVENT_TO_STRING_BUF_SIZE];
- gs_free char *hwaddr_str = NULL;
- gboolean check_probing_done = FALSE;
-
- switch (event->event) {
- case N_ACD_EVENT_READY:
- n_acd_probe_get_userdata(event->ready.probe, (void **) &info);
- info->duplicate = FALSE;
- if (self->state == STATE_ANNOUNCING) {
- /* fake probe ended, start announcing */
- r = n_acd_probe_announce(info->probe, N_ACD_DEFEND_ONCE);
- if (r) {
- _LOGW("couldn't announce address %s on interface '%s': %s",
- _nm_utils_inet4_ntop(info->address, address_str),
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex),
- acd_error_to_string(r));
- } else {
- _LOGD("announcing address %s",
- _nm_utils_inet4_ntop(info->address, address_str));
- }
- }
- check_probing_done = TRUE;
- break;
- case N_ACD_EVENT_USED:
- n_acd_probe_get_userdata(event->used.probe, (void **) &info);
- info->duplicate = TRUE;
- check_probing_done = TRUE;
- break;
- case N_ACD_EVENT_DEFENDED:
- n_acd_probe_get_userdata(event->defended.probe, (void **) &info);
- _LOGD("defended address %s from host %s",
- _nm_utils_inet4_ntop(info->address, address_str),
- (hwaddr_str =
- nm_utils_hwaddr_ntoa(event->defended.sender, event->defended.n_sender)));
- break;
- case N_ACD_EVENT_CONFLICT:
- n_acd_probe_get_userdata(event->conflict.probe, (void **) &info);
- _LOGW("conflict for address %s detected with host %s on interface '%s'",
- _nm_utils_inet4_ntop(info->address, address_str),
- (hwaddr_str =
- nm_utils_hwaddr_ntoa(event->defended.sender, event->defended.n_sender)),
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex));
- break;
- default:
- _LOGD("unhandled event '%s'", _acd_event_to_string_buf(event->event, to_string_buffer));
- break;
- }
-
- if (check_probing_done && self->state == STATE_PROBING
- && ++self->completed == g_hash_table_size(self->addresses)) {
- self->state = STATE_PROBE_DONE;
- emit_probe_terminated = TRUE;
- }
- }
-
- if (emit_probe_terminated) {
- if (self->callbacks.probe_terminated_callback) {
- self->callbacks.probe_terminated_callback(self, self->user_data);
- }
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-static gboolean
-acd_probe_add(NMAcdManager *self, AddressInfo *info, guint64 timeout)
-{
- NAcdProbeConfig *probe_config;
- int r;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
-
- r = n_acd_probe_config_new(&probe_config);
- if (r) {
- _LOGW("could not create probe config for %s on interface '%s': %s",
- _nm_utils_inet4_ntop(info->address, sbuf),
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex),
- acd_error_to_string(r));
- return FALSE;
- }
-
- n_acd_probe_config_set_ip(probe_config, (struct in_addr){info->address});
- n_acd_probe_config_set_timeout(probe_config, timeout);
-
- r = n_acd_probe(self->acd, &info->probe, probe_config);
- if (r) {
- _LOGW("could not start probe for %s on interface '%s': %s",
- _nm_utils_inet4_ntop(info->address, sbuf),
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex),
- acd_error_to_string(r));
- n_acd_probe_config_free(probe_config);
- return FALSE;
- }
-
- n_acd_probe_set_userdata(info->probe, info);
- n_acd_probe_config_free(probe_config);
-
- return TRUE;
-}
-
-static int
-acd_init(NMAcdManager *self)
-{
- NAcdConfig *config;
- int r;
-
- if (self->acd)
- return 0;
-
- r = n_acd_config_new(&config);
- if (r)
- return r;
-
- n_acd_config_set_ifindex(config, self->ifindex);
- n_acd_config_set_transport(config, N_ACD_TRANSPORT_ETHERNET);
- n_acd_config_set_mac(config, self->hwaddr, ETH_ALEN);
-
- r = n_acd_new(&self->acd, config);
- n_acd_config_free(config);
- return r;
-}
-
-/**
- * nm_acd_manager_start_probe:
- * @self: a #NMAcdManager
- * @timeout: maximum probe duration in milliseconds
- * @error: location to store error, or %NULL
- *
- * Start probing IP addresses for duplicates; when the probe terminates a
- * PROBE_TERMINATED signal is emitted.
- *
- * Returns: 0 on success or a negative NetworkManager error code (NME_*).
- */
-int
-nm_acd_manager_start_probe(NMAcdManager *self, guint timeout)
-{
- GHashTableIter iter;
- AddressInfo * info;
- gboolean success = FALSE;
- int fd, r;
-
- g_return_val_if_fail(self, FALSE);
- g_return_val_if_fail(self->state == STATE_INIT, FALSE);
-
- r = acd_init(self);
- if (r) {
- _LOGW("couldn't init ACD for probing on interface '%s': %s",
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex),
- acd_error_to_string(r));
- return acd_error_to_nmerr(r, TRUE);
- }
-
- self->completed = 0;
-
- g_hash_table_iter_init(&iter, self->addresses);
- while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &info))
- success |= acd_probe_add(self, info, timeout);
-
- if (success)
- self->state = STATE_PROBING;
-
- nm_assert(!self->event_source);
- n_acd_get_fd(self->acd, &fd);
- self->event_source =
- nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, acd_event, self, NULL);
- g_source_attach(self->event_source, NULL);
-
- return success ? 0 : -NME_UNSPEC;
-}
-
-/**
- * nm_acd_manager_check_address:
- * @self: a #NMAcdManager
- * @address: an IP address
- *
- * Check if an IP address is duplicate. @address must have been added with
- * nm_acd_manager_add_address().
- *
- * Returns: %TRUE if the address is not duplicate, %FALSE otherwise
- */
-gboolean
-nm_acd_manager_check_address(NMAcdManager *self, in_addr_t address)
-{
- AddressInfo *info;
-
- g_return_val_if_fail(self, FALSE);
- g_return_val_if_fail(NM_IN_SET(self->state, STATE_INIT, STATE_PROBE_DONE), FALSE);
-
- info = g_hash_table_lookup(self->addresses, GUINT_TO_POINTER(address));
- g_return_val_if_fail(info, FALSE);
-
- return !info->duplicate;
-}
-
-/**
- * nm_acd_manager_announce_addresses:
- * @self: a #NMAcdManager
- *
- * Start announcing addresses.
- *
- * Returns: a negative NetworkManager error number or zero on success.
- */
-int
-nm_acd_manager_announce_addresses(NMAcdManager *self)
-{
- GHashTableIter iter;
- AddressInfo * info;
- int r;
- int fd;
- gboolean success = TRUE;
-
- r = acd_init(self);
- if (r) {
- _LOGW("couldn't init ACD for announcing addresses on interface '%s': %s",
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex),
- acd_error_to_string(r));
- return acd_error_to_nmerr(r, TRUE);
- }
-
- if (self->state == STATE_INIT) {
- /* n-acd can't announce without probing, therefore let's
- * start a fake probe with zero timeout and then perform
- * the announcement. */
- g_hash_table_iter_init(&iter, self->addresses);
- while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &info)) {
- if (!acd_probe_add(self, info, 0))
- success = FALSE;
- }
- self->state = STATE_ANNOUNCING;
- } else if (self->state == STATE_ANNOUNCING) {
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
-
- g_hash_table_iter_init(&iter, self->addresses);
- while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &info)) {
- if (info->duplicate)
- continue;
- r = n_acd_probe_announce(info->probe, N_ACD_DEFEND_ONCE);
- if (r) {
- _LOGW("couldn't announce address %s on interface '%s': %s",
- _nm_utils_inet4_ntop(info->address, sbuf),
- nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex),
- acd_error_to_string(r));
- success = FALSE;
- } else
- _LOGD("announcing address %s", _nm_utils_inet4_ntop(info->address, sbuf));
- }
- }
-
- if (!self->event_source) {
- n_acd_get_fd(self->acd, &fd);
- self->event_source =
- nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, acd_event, self, NULL);
- g_source_attach(self->event_source, NULL);
- }
-
- return success ? 0 : -NME_UNSPEC;
-}
-
-static void
-destroy_address_info(gpointer data)
-{
- AddressInfo *info = (AddressInfo *) data;
-
- n_acd_probe_free(info->probe);
-
- g_slice_free(AddressInfo, info);
-}
-
-/*****************************************************************************/
-
-NMAcdManager *
-nm_acd_manager_new(int ifindex,
- const guint8 * hwaddr,
- guint hwaddr_len,
- const NMAcdCallbacks *callbacks,
- gpointer user_data)
-{
- NMAcdManager *self;
-
- g_return_val_if_fail(ifindex > 0, NULL);
- g_return_val_if_fail(hwaddr, NULL);
- g_return_val_if_fail(hwaddr_len == ETH_ALEN, NULL);
-
- self = g_slice_new0(NMAcdManager);
-
- if (callbacks)
- self->callbacks = *callbacks;
- self->user_data = user_data;
-
- self->addresses = g_hash_table_new_full(nm_direct_hash, NULL, NULL, destroy_address_info);
- self->state = STATE_INIT;
- self->ifindex = ifindex;
- memcpy(self->hwaddr, hwaddr, ETH_ALEN);
- return self;
-}
-
-void
-nm_acd_manager_free(NMAcdManager *self)
-{
- g_return_if_fail(self);
-
- if (self->callbacks.user_data_destroy)
- self->callbacks.user_data_destroy(self->user_data);
-
- nm_clear_pointer(&self->addresses, g_hash_table_destroy);
- nm_clear_g_source_inst(&self->event_source);
- nm_clear_pointer(&self->acd, n_acd_unref);
-
- g_slice_free(NMAcdManager, self);
-}
diff --git a/src/core/devices/nm-acd-manager.h b/src/core/devices/nm-acd-manager.h
deleted file mode 100644
index e8ef6f2b99..0000000000
--- a/src/core/devices/nm-acd-manager.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2015 - 2018 Red Hat, Inc.
- */
-
-#ifndef __NM_ACD_MANAGER__
-#define __NM_ACD_MANAGER__
-
-#include <netinet/in.h>
-
-typedef struct _NMAcdManager NMAcdManager;
-
-typedef struct {
- void (*probe_terminated_callback)(NMAcdManager *self, gpointer user_data);
- GDestroyNotify user_data_destroy;
-} NMAcdCallbacks;
-
-NMAcdManager *nm_acd_manager_new(int ifindex,
- const guint8 * hwaddr,
- guint hwaddr_len,
- const NMAcdCallbacks *callbacks,
- gpointer user_data);
-
-void nm_acd_manager_free(NMAcdManager *self);
-
-gboolean nm_acd_manager_add_address(NMAcdManager *self, in_addr_t address);
-int nm_acd_manager_start_probe(NMAcdManager *self, guint timeout);
-gboolean nm_acd_manager_check_address(NMAcdManager *self, in_addr_t address);
-int nm_acd_manager_announce_addresses(NMAcdManager *self);
-
-NM_AUTO_DEFINE_FCN0(NMAcdManager *, _nm_auto_free_acdmgr, nm_acd_manager_free);
-#define nm_auto_free_acdmgr nm_auto(_nm_auto_free_acdmgr)
-
-#endif /* __NM_ACD_MANAGER__ */
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c
index 3b3b8fcdd3..73ec0474f9 100644
--- a/src/core/devices/nm-device-bond.c
+++ b/src/core/devices/nm-device-bond.c
@@ -15,7 +15,6 @@
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#include "libnm-core-intern/nm-core-internal.h"
-#include "nm-ip4-config.h"
#define _NMLOG_DEVICE_TYPE NMDeviceBond
#include "nm-device-logging.h"
diff --git a/src/core/devices/nm-device-dummy.c b/src/core/devices/nm-device-dummy.c
index 488f0ba003..2f8f311e23 100644
--- a/src/core/devices/nm-device-dummy.c
+++ b/src/core/devices/nm-device-dummy.c
@@ -12,7 +12,6 @@
#include "nm-act-request.h"
#include "nm-device-private.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#include "nm-setting-dummy.h"
diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c
index 305552f074..153938ba40 100644
--- a/src/core/devices/nm-device-ethernet.c
+++ b/src/core/devices/nm-device-ethernet.c
@@ -17,7 +17,6 @@
#include "libnm-glib-aux/nm-uuid.h"
#include "nm-device-private.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
#include "NetworkManagerUtils.h"
#include "supplicant/nm-supplicant-manager.h"
#include "supplicant/nm-supplicant-interface.h"
@@ -1136,13 +1135,24 @@ ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpoin
}
static void
-ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data)
+ppp_new_config(NMPPPManager * ppp_manager,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ const NMUtilsIPv6IfaceId *iid,
+ gpointer user_data)
{
NMDevice *device = NM_DEVICE(user_data);
- /* Ignore PPP IP4 events that come in after initial configuration */
- if (nm_device_activate_ip4_state_in_conf(device))
- nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config));
+ if (addr_family != AF_INET)
+ return;
+
+ if (!nm_device_activate_ip4_state_in_conf(device)) {
+ /* Ignore PPP IP4 events that come in after initial configuration */
+ return;
+ }
+
+ nm_device_set_dev2_ip_config(device, AF_INET, l3cd);
+ nm_device_activate_schedule_ip_config_result(device, AF_INET);
}
static NMActStageReturn
@@ -1164,14 +1174,6 @@ pppoe_stage3_ip4_config_start(NMDeviceEthernet *self, NMDeviceStateReason *out_f
priv->ppp_manager = nm_ppp_manager_create(nm_device_get_iface(device), &err);
- if (priv->ppp_manager) {
- nm_ppp_manager_set_route_parameters(priv->ppp_manager,
- nm_device_get_route_table(device, AF_INET),
- nm_device_get_route_metric(device, AF_INET),
- nm_device_get_route_table(device, AF_INET6),
- nm_device_get_route_metric(device, AF_INET6));
- }
-
if (!priv->ppp_manager
|| !nm_ppp_manager_start(priv->ppp_manager,
req,
@@ -1197,8 +1199,8 @@ pppoe_stage3_ip4_config_start(NMDeviceEthernet *self, NMDeviceStateReason *out_f
G_CALLBACK(ppp_ifindex_set),
self);
g_signal_connect(priv->ppp_manager,
- NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
- G_CALLBACK(ppp_ip4_config),
+ NM_PPP_MANAGER_SIGNAL_NEW_CONFIG,
+ G_CALLBACK(ppp_new_config),
self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -1496,10 +1498,10 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_config,
+ NMDeviceStateReason * out_failure_reason)
{
NMSettingConnection *s_con;
const char * connection_type;
diff --git a/src/core/devices/nm-device-infiniband.c b/src/core/devices/nm-device-infiniband.c
index 37065bc89f..5c3064468e 100644
--- a/src/core/devices/nm-device-infiniband.c
+++ b/src/core/devices/nm-device-infiniband.c
@@ -13,7 +13,6 @@
#include "NetworkManagerUtils.h"
#include "nm-device-private.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#include "libnm-core-intern/nm-core-internal.h"
diff --git a/src/core/devices/nm-device-ip-tunnel.c b/src/core/devices/nm-device-ip-tunnel.c
index c55dd9f6b2..7f3c0b44f6 100644
--- a/src/core/devices/nm-device-ip-tunnel.c
+++ b/src/core/devices/nm-device-ip-tunnel.c
@@ -21,7 +21,6 @@
#include "libnm-core-intern/nm-core-internal.h"
#include "settings/nm-settings.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
#define _NMLOG_DEVICE_TYPE NMDeviceIPTunnel
#include "nm-device-logging.h"
diff --git a/src/core/devices/nm-device-macvlan.c b/src/core/devices/nm-device-macvlan.c
index 7302ecdf2d..87c18ebe3d 100644
--- a/src/core/devices/nm-device-macvlan.c
+++ b/src/core/devices/nm-device-macvlan.c
@@ -18,7 +18,6 @@
#include "nm-setting-macvlan.h"
#include "nm-setting-wired.h"
#include "nm-active-connection.h"
-#include "nm-ip4-config.h"
#include "nm-utils.h"
#define _NMLOG_DEVICE_TYPE NMDeviceMacvlan
diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c
index 8df245bb0f..c593459685 100644
--- a/src/core/devices/nm-device-ppp.c
+++ b/src/core/devices/nm-device-ppp.c
@@ -7,7 +7,7 @@
#include "nm-device-ppp.h"
-#include "nm-ip4-config.h"
+#include "nm-l3-config-data.h"
#include "nm-act-request.h"
#include "nm-device-factory.h"
#include "nm-device-private.h"
@@ -24,8 +24,8 @@
/*****************************************************************************/
typedef struct _NMDevicePppPrivate {
- NMPPPManager *ppp_manager;
- NMIP4Config * ip4_config;
+ NMPPPManager * ppp_manager;
+ const NML3ConfigData *l3cd_4;
} NMDevicePppPrivate;
struct _NMDevicePpp {
@@ -93,26 +93,31 @@ ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpoin
}
static void
-ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data)
+ppp_new_config(NMPPPManager * ppp_manager,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ const NMUtilsIPv6IfaceId *iid,
+ gpointer user_data)
{
NMDevice * device = NM_DEVICE(user_data);
NMDevicePpp * self = NM_DEVICE_PPP(device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self);
+ if (addr_family != AF_INET)
+ return;
+
_LOGT(LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd");
- if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG) {
- if (nm_device_activate_ip4_state_in_conf(device)) {
- nm_device_activate_schedule_ip_config_result(device,
- AF_INET,
- NM_IP_CONFIG_CAST(config));
- return;
- }
- } else {
- if (priv->ip4_config)
- g_object_unref(priv->ip4_config);
- priv->ip4_config = g_object_ref(config);
+ if (nm_device_get_state(device) != NM_DEVICE_STATE_IP_CONFIG) {
+ nm_l3_config_data_reset(&priv->l3cd_4, l3cd);
+ return;
}
+
+ if (!nm_device_activate_ip4_state_in_conf(device))
+ return;
+
+ nm_device_set_dev2_ip_config(device, AF_INET, l3cd);
+ nm_device_activate_schedule_ip_config_result(device, AF_INET);
}
static gboolean
@@ -150,18 +155,10 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
s_pppoe = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE);
g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
- g_clear_object(&priv->ip4_config);
+ nm_clear_l3cd(&priv->l3cd_4);
priv->ppp_manager = nm_ppp_manager_create(nm_setting_pppoe_get_parent(s_pppoe), &error);
- if (priv->ppp_manager) {
- nm_ppp_manager_set_route_parameters(priv->ppp_manager,
- nm_device_get_route_table(device, AF_INET),
- nm_device_get_route_metric(device, AF_INET),
- nm_device_get_route_table(device, AF_INET6),
- nm_device_get_route_metric(device, AF_INET6));
- }
-
if (!priv->ppp_manager
|| !nm_ppp_manager_start(priv->ppp_manager,
req,
@@ -187,27 +184,27 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
G_CALLBACK(ppp_ifindex_set),
self);
g_signal_connect(priv->ppp_manager,
- NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
- G_CALLBACK(ppp_ip4_config),
+ NM_PPP_MANAGER_SIGNAL_NEW_CONFIG,
+ G_CALLBACK(ppp_new_config),
self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
if (addr_family == AF_INET) {
NMDevicePpp * self = NM_DEVICE_PPP(device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self);
- if (priv->ip4_config) {
- if (out_config)
- *out_config = g_steal_pointer(&priv->ip4_config);
+ if (priv->l3cd_4) {
+ if (out_l3cd)
+ *out_l3cd = g_steal_pointer(&priv->l3cd_4);
else
- g_clear_object(&priv->ip4_config);
+ nm_clear_l3cd(&priv->l3cd_4);
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@@ -216,7 +213,7 @@ act_stage3_ip_config_start(NMDevice * device,
}
return NM_DEVICE_CLASS(nm_device_ppp_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static gboolean
@@ -268,7 +265,7 @@ dispose(GObject *object)
NMDevicePpp * self = NM_DEVICE_PPP(object);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self);
- g_clear_object(&priv->ip4_config);
+ nm_clear_l3cd(&priv->l3cd_4);
G_OBJECT_CLASS(nm_device_ppp_parent_class)->dispose(object);
}
diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h
index eb37b14ffb..73d3f7de36 100644
--- a/src/core/devices/nm-device-private.h
+++ b/src/core/devices/nm-device-private.h
@@ -34,8 +34,6 @@ enum NMActStageReturn {
#define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000
-void nm_device_arp_announce(NMDevice *self);
-
NMSettings *nm_device_get_settings(NMDevice *self);
NMManager *nm_device_get_manager(NMDevice *self);
@@ -66,8 +64,7 @@ void nm_device_set_firmware_missing(NMDevice *self, gboolean missing);
void nm_device_activate_schedule_stage1_device_prepare(NMDevice *device, gboolean do_sync);
void nm_device_activate_schedule_stage2_device_config(NMDevice *device, gboolean do_sync);
-void
-nm_device_activate_schedule_ip_config_result(NMDevice *device, int addr_family, NMIPConfig *config);
+void nm_device_activate_schedule_ip_config_result(NMDevice *device, int addr_family);
void nm_device_activate_schedule_ip_config_timeout(NMDevice *device, int addr_family);
@@ -109,8 +106,7 @@ nm_device_activate_ip6_state_done(NMDevice *self)
return nm_device_activate_get_ip_state(self, AF_INET6) == NM_DEVICE_IP_STATE_DONE;
}
-gboolean nm_device_dhcp4_renew(NMDevice *device, gboolean release);
-gboolean nm_device_dhcp6_renew(NMDevice *device, gboolean release);
+gboolean nm_device_dhcp_renew(NMDevice *device, int addr_family, gboolean release);
void nm_device_recheck_available_connections(NMDevice *device);
@@ -126,7 +122,7 @@ void nm_device_queue_recheck_available(NMDevice * device,
NMDeviceStateReason available_reason,
NMDeviceStateReason unavailable_reason);
-void nm_device_set_dev2_ip_config(NMDevice *device, int addr_family, NMIPConfig *config);
+void nm_device_set_dev2_ip_config(NMDevice *device, int addr_family, const NML3ConfigData *l3cd);
gboolean nm_device_hw_addr_is_explict(NMDevice *device);
@@ -137,11 +133,7 @@ gboolean nm_device_sysctl_ip_conf_set(NMDevice * self,
const char *property,
const char *value);
-NMIP4Config *nm_device_ip4_config_new(NMDevice *self);
-
-NMIP6Config *nm_device_ip6_config_new(NMDevice *self);
-
-NMIPConfig *nm_device_ip_config_new(NMDevice *self, int addr_family);
+NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self);
NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self);
diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c
index ebccddfcf8..e622b7a87c 100644
--- a/src/core/devices/nm-device-tun.c
+++ b/src/core/devices/nm-device-tun.c
@@ -13,7 +13,6 @@
#include "nm-act-request.h"
#include "nm-device-private.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#include "nm-setting-tun.h"
diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c
index 548245f80c..c989dbabc5 100644
--- a/src/core/devices/nm-device-vlan.c
+++ b/src/core/devices/nm-device-vlan.c
@@ -15,7 +15,6 @@
#include "nm-device-private.h"
#include "settings/nm-settings.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#include "nm-manager.h"
@@ -112,7 +111,6 @@ parent_hwaddr_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_d
NM_PRINT_FMT_QUOTE_STRING(new_mac));
if (new_mac) {
nm_device_hw_addr_set(device, new_mac, "vlan-parent", TRUE);
- nm_device_arp_announce(device);
/* When changing the hw address the interface is taken down,
* removing the IPv6 configuration; reapply it.
*/
diff --git a/src/core/devices/nm-device-vxlan.c b/src/core/devices/nm-device-vxlan.c
index f9dfad2a82..035acf873b 100644
--- a/src/core/devices/nm-device-vxlan.c
+++ b/src/core/devices/nm-device-vxlan.c
@@ -16,7 +16,6 @@
#include "nm-setting-wired.h"
#include "settings/nm-settings.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
#include "libnm-core-intern/nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceVxlan
diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c
index aa9c46eba6..f305a5c67a 100644
--- a/src/core/devices/nm-device-wireguard.c
+++ b/src/core/devices/nm-device-wireguard.c
@@ -11,6 +11,7 @@
#include <linux/fib_rules.h>
#include "nm-setting-wireguard.h"
+#include "nm-l3-config-data.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-glib-aux/nm-secret-utils.h"
#include "nm-device-private.h"
@@ -1624,19 +1625,19 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
return ret;
}
-static NMIPConfig *
+static const NML3ConfigData *
_get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family)
{
- NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self);
- gs_unref_object NMIPConfig *ip_config = NULL;
- NMConnection * connection;
- NMSettingWireGuard * s_wg;
- guint n_peers;
- guint i;
- int ip_ifindex;
- guint32 route_metric;
- guint32 route_table_coerced;
- gboolean auto_default_route_enabled;
+ NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMConnection * connection;
+ NMSettingWireGuard * s_wg;
+ guint n_peers;
+ guint i;
+ int ip_ifindex;
+ guint32 route_metric;
+ guint32 route_table_coerced;
+ gboolean auto_default_route_enabled;
_auto_default_route_init(self);
@@ -1714,11 +1715,10 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family)
continue;
}
- if (!ip_config) {
- ip_config = nm_device_ip_config_new(NM_DEVICE(self), addr_family);
- nm_ip_config_set_config_flags(ip_config,
- NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES,
- 0);
+ if (!l3cd) {
+ l3cd = nm_device_create_l3_config_data(NM_DEVICE(self));
+ nm_l3_config_data_set_flags(l3cd,
+ NM_L3_CONFIG_DAT_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES);
}
nm_utils_ipx_address_clear_host_address(addr_family, &addrbin, NULL, prefix);
@@ -1753,27 +1753,30 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family)
};
}
- nm_ip_config_add_route(ip_config, &rt.rx, NULL);
+ nm_l3_config_data_add_route(l3cd, addr_family, NULL, &rt.rx);
}
}
- return g_steal_pointer(&ip_config);
+ if (!l3cd)
+ return NULL;
+
+ return nm_l3_config_data_seal(g_steal_pointer(&l3cd));
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
- gs_unref_object NMIPConfig *ip_config = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
- ip_config = _get_dev2_ip_config(NM_DEVICE_WIREGUARD(device), addr_family);
+ l3cd = _get_dev2_ip_config(NM_DEVICE_WIREGUARD(device), addr_family);
- nm_device_set_dev2_ip_config(device, addr_family, ip_config);
+ nm_device_set_dev2_ip_config(device, addr_family, l3cd);
return NM_DEVICE_CLASS(nm_device_wireguard_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static guint32
@@ -1863,11 +1866,9 @@ can_reapply_change(NMDevice * device,
static void
reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new)
{
- NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(device);
- NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self);
- gs_unref_object NMIPConfig *ip4_config = NULL;
- gs_unref_object NMIPConfig *ip6_config = NULL;
- NMDeviceState state = nm_device_get_state(device);
+ NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(device);
+ NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self);
+ NMDeviceState state = nm_device_get_state(device);
NM_DEVICE_CLASS(nm_device_wireguard_parent_class)->reapply_connection(device, con_old, con_new);
@@ -1877,11 +1878,14 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne
}
if (state >= NM_DEVICE_STATE_IP_CONFIG) {
- ip4_config = _get_dev2_ip_config(self, AF_INET);
- ip6_config = _get_dev2_ip_config(self, AF_INET6);
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_4 = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_6 = NULL;
+
+ l3cd_4 = _get_dev2_ip_config(self, AF_INET);
+ l3cd_6 = _get_dev2_ip_config(self, AF_INET6);
- nm_device_set_dev2_ip_config(device, AF_INET, ip4_config);
- nm_device_set_dev2_ip_config(device, AF_INET6, ip6_config);
+ nm_device_set_dev2_ip_config(device, AF_INET, l3cd_4);
+ nm_device_set_dev2_ip_config(device, AF_INET6, l3cd_6);
}
}
diff --git a/src/core/devices/nm-device-wpan.c b/src/core/devices/nm-device-wpan.c
index 73d7941001..2486f18c2d 100644
--- a/src/core/devices/nm-device-wpan.c
+++ b/src/core/devices/nm-device-wpan.c
@@ -14,7 +14,6 @@
#include "nm-act-request.h"
#include "nm-device-private.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#include "nm-setting-wpan.h"
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 21863b9533..ba59d4f53c 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -34,6 +34,7 @@
#include "nm-device-private.h"
#include "nm-l3cfg.h"
#include "nm-l3-config-data.h"
+#include "nm-l3-ipv4ll.h"
#include "NetworkManagerUtils.h"
#include "nm-manager.h"
#include "libnm-platform/nm-platform.h"
@@ -45,11 +46,9 @@
#include "dhcp/nm-dhcp-manager.h"
#include "dhcp/nm-dhcp-utils.h"
#include "nm-act-request.h"
-#include "nm-proxy-config.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
#include "nm-pacrunner-manager.h"
#include "dnsmasq/nm-dnsmasq-manager.h"
+#include "nm-ip-config.h"
#include "nm-dhcp-config.h"
#include "nm-rfkill-manager.h"
#include "nm-firewall-utils.h"
@@ -66,7 +65,6 @@
#include "nm-config.h"
#include "c-list/src/c-list.h"
#include "dns/nm-dns-manager.h"
-#include "nm-acd-manager.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-systemd-core/nm-sd.h"
#include "nm-lldp-listener.h"
@@ -85,19 +83,8 @@
#define DEFAULT_AUTOCONNECT TRUE
-static guint32
-dhcp_grace_period_from_timeout(guint32 timeout)
-{
-#define DHCP_GRACE_PERIOD_MULTIPLIER 2U
-
- nm_assert(timeout > 0);
- nm_assert(timeout < G_MAXINT32);
-
- if (timeout < G_MAXUINT32 / DHCP_GRACE_PERIOD_MULTIPLIER)
- return timeout * DHCP_GRACE_PERIOD_MULTIPLIER;
-
- return G_MAXUINT32;
-}
+//XXX: drop GRACE_PERIOD_MULTIPLIER or review it at least.
+#define GRACE_PERIOD_MULTIPLIER 2U
#define CARRIER_WAIT_TIME_MS 6000
#define CARRIER_WAIT_TIME_AFTER_MTU_MS 10000
@@ -116,6 +103,13 @@ typedef enum {
CLEANUP_TYPE_DECONFIGURE,
} CleanupType;
+typedef enum _nm_packed {
+ ADDR_METHOD_STATE_DISABLED,
+ ADDR_METHOD_STATE_PENDING,
+ ADDR_METHOD_STATE_GOOD,
+ ADDR_METHOD_STATE_FAILED,
+} AddrMethodState;
+
typedef struct {
CList lst_slave;
NMDevice *slave;
@@ -138,28 +132,40 @@ typedef struct {
NMOptionBool autoprobe;
} SriovOp;
-typedef void (*AcdCallback)(NMDevice *, NMIP4Config **, gboolean);
-
typedef enum {
/* The various NML3ConfigData types that we track explicitly. Note that
* their relative order matters: higher numbers in this enum means more
* important (and during merge overwrites other settings). */
+
L3_CONFIG_DATA_TYPE_LL_4,
+ L3_CONFIG_DATA_TYPE_LL_6,
+
+#define L3_CONFIG_DATA_TYPE_LL(IS_IPv4) \
+ ((IS_IPv4) ? L3_CONFIG_DATA_TYPE_LL_4 : L3_CONFIG_DATA_TYPE_LL_6)
+
L3_CONFIG_DATA_TYPE_AC_6,
+ L3_CONFIG_DATA_TYPE_PD_6,
+
L3_CONFIG_DATA_TYPE_DHCP_4,
L3_CONFIG_DATA_TYPE_DHCP_6,
+
+#define L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4) \
+ ((IS_IPv4) ? L3_CONFIG_DATA_TYPE_DHCP_4 : L3_CONFIG_DATA_TYPE_DHCP_6)
+
+ L3_CONFIG_DATA_TYPE_SHARED_4,
L3_CONFIG_DATA_TYPE_DEV_4,
L3_CONFIG_DATA_TYPE_DEV_6,
+
+#define L3_CONFIG_DATA_TYPE_DEV_X(IS_IPv4) \
+ ((IS_IPv4) ? L3_CONFIG_DATA_TYPE_DEV_4 : L3_CONFIG_DATA_TYPE_DEV_6)
+
L3_CONFIG_DATA_TYPE_SETTING,
+
_L3_CONFIG_DATA_TYPE_NUM,
_L3_CONFIG_DATA_TYPE_NONE,
} L3ConfigDataType;
-typedef struct {
- AcdCallback callback;
- NMDevice * device;
- NMIP4Config **configs;
-} AcdData;
+G_STATIC_ASSERT(NM_L3CFG_CONFIG_PRIORITY_IPV4LL == L3_CONFIG_DATA_TYPE_LL_4);
typedef enum {
HW_ADDR_TYPE_UNSET = 0,
@@ -175,19 +181,47 @@ typedef enum {
FIREWALL_STATE_WAIT_IP_CONFIG,
} FirewallState;
-typedef struct {
- NMIPConfig *orig; /* the original configuration applied to the device */
- NMIPConfig *current; /* configuration after external changes. NULL means
- * that the original configuration didn't change. */
-} AppliedConfig;
+typedef enum _nm_packed {
+ DHCP_STATE_NONE,
+
+ /* NMDhcpClient is in SELECTING state (or retrying). */
+ DHCP_STATE_SELECTING,
+
+ /* We have a lease, but are currently performing ACD on the
+ * address. */
+ DHCP_STATE_PROBING,
+
+ /* ACD passed and we accept the lease. */
+ DHCP_STATE_BOUND,
+
+ /* ACD failed, lease timeout or timeout obtaining a lease. This is similar to
+ * DHCP_STATE_SELECTING in that we try to re-get a lease in the background.
+ * But we also might fail the connection as a whole in this event.
+ *
+ * In this case, we also might have the grace timer running. */
+ DHCP_STATE_FAILED,
+} DhcpState;
+
+static NM_UTILS_LOOKUP_STR_DEFINE(_dhcp_state_to_string,
+ DhcpState,
+ NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(NULL),
+ NM_UTILS_LOOKUP_STR_ITEM(DHCP_STATE_NONE, "none"),
+ NM_UTILS_LOOKUP_STR_ITEM(DHCP_STATE_SELECTING, "selecting"),
+ NM_UTILS_LOOKUP_STR_ITEM(DHCP_STATE_BOUND, "bound"),
+ NM_UTILS_LOOKUP_STR_ITEM(DHCP_STATE_PROBING, "probing"),
+ NM_UTILS_LOOKUP_STR_ITEM(DHCP_STATE_FAILED, "failed"), );
typedef struct {
NMDhcpClient *client;
NMDhcpConfig *config;
- gulong state_sigid;
- guint grace_id;
- bool grace_pending : 1;
- bool was_active : 1;
+
+ /* this is a timer ticking from when we start doing DHCP until
+ * ipv[46].dhcp-timeout expires. After that, we either fail the
+ * connection or we keep trying in the background. */
+ GSource *grace_source;
+
+ gulong state_sigid;
+ DhcpState state;
} DhcpData;
struct _NMDeviceConnectivityHandle {
@@ -234,8 +268,7 @@ typedef struct {
enum {
STATE_CHANGED,
AUTOCONNECT_ALLOWED,
- IP4_CONFIG_CHANGED,
- IP6_CONFIG_CHANGED,
+ L3CD_CHANGED,
IP6_PREFIX_DELEGATED,
IP6_SUBNET_NEEDED,
REMOVED,
@@ -260,6 +293,9 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice,
PROP_IP4_ADDRESS,
PROP_IP4_CONFIG,
PROP_DHCP4_CONFIG,
+
+#define PROP_DHCPX_CONFIG(IS_IPv4) ((IS_IPv4) ? PROP_DHCP4_CONFIG : PROP_DHCP6_CONFIG)
+
PROP_IP6_CONFIG,
PROP_DHCP6_CONFIG,
PROP_STATE,
@@ -293,8 +329,6 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice,
PROP_INTERFACE_FLAGS, );
typedef struct _NMDevicePrivate {
- bool in_state_changed;
-
guint device_link_changed_id;
guint device_ip_link_changed_id;
@@ -308,16 +342,7 @@ typedef struct _NMDevicePrivate {
NMDeviceStateReason reason;
} queued_state;
- union {
- struct {
- guint queued_ip_config_id_6;
- guint queued_ip_config_id_4;
- };
- guint queued_ip_config_id_x[2];
- };
-
GSList *pending_actions;
- GSList *dad6_failed_addrs;
NMDBusTrackObjPath parent_device;
@@ -334,15 +359,30 @@ typedef struct _NMDevicePrivate {
};
union {
+ NML3Cfg *const l3cfg;
+ NML3Cfg * l3cfg_;
+ };
+
+ NML3CfgCommitTypeHandle *l3cfg_commit_type;
+
+ union {
const int ifindex;
int ifindex_;
};
+
union {
const int ip_ifindex;
int ip_ifindex_;
};
- NMNetnsSharedIPHandle *shared_ip_handle;
+ union {
+ const NML3ConfigData * d;
+ const NML3ConfigData *const d_;
+ } l3cds[_L3_CONFIG_DATA_TYPE_NUM];
+
+ NMNetnsSharedIPHandle *shared4_ip_handle;
+
+ NMFirewallConfig *firewall_config;
int parent_ifindex;
@@ -365,9 +405,6 @@ typedef struct _NMDevicePrivate {
bool real : 1;
- bool update_ip_config_completed_v4 : 1;
- bool update_ip_config_completed_v6 : 1;
-
NMDeviceType type;
char * type_desc;
NMLinkType link_type;
@@ -381,6 +418,8 @@ typedef struct _NMDevicePrivate {
bool
hw_addr_perm_fake : 1; /* whether the permanent HW address could not be read and is a fake */
+ guint8 in_state_changed : 4;
+
NMUtilsStableType current_stable_id_type : 3;
bool nm_owned : 1; /* whether the device is a device owned and created by NM */
@@ -446,7 +485,7 @@ typedef struct _NMDevicePrivate {
gulong config_changed_id;
gulong ifindex_changed_id;
guint32 mtu;
- guint32 ip6_mtu;
+ guint32 ip6_mtu; /* FIXME(l3cfg) */
guint32 mtu_initial;
guint32 ip6_mtu_initial;
NMDeviceMtuSource mtu_source;
@@ -463,6 +502,14 @@ typedef struct _NMDevicePrivate {
gint64 carrier_wait_until_ms;
union {
+ struct {
+ NML3ConfigMergeFlags l3config_merge_flags_6;
+ NML3ConfigMergeFlags l3config_merge_flags_4;
+ };
+ NML3ConfigMergeFlags l3config_merge_flags_x[2];
+ };
+
+ union {
const NMDeviceSysIfaceState sys_iface_state;
NMDeviceSysIfaceState sys_iface_state_;
};
@@ -492,78 +539,33 @@ typedef struct _NMDevicePrivate {
bool ipv6ll_handle : 1; /* TRUE if NM handles the device's IPv6LL address */
bool ipv6ll_has : 1;
- bool ndisc_started : 1;
+ bool ac6_ndisc_started : 1;
+ bool ac6_ndisc_grace_pending : 1;
bool device_link_changed_down : 1;
bool concheck_rp_filter_checked : 1;
+ bool ll4_ipv4ll_ready : 1;
+ bool ll4_ipv4ll_failed : 1;
+
NMDeviceStageState stage1_sriov_state : 3;
+ GSource *ac6_ndisc_grace_source;
+
char *current_stable_id;
- /* Proxy Configuration */
- NMProxyConfig * proxy_config;
NMPacrunnerConfId *pacrunner_conf_id;
- /* IP configuration info. Combined config from VPN, settings, and device */
union {
struct {
- NMIP6Config *ip_config_6;
- NMIP4Config *ip_config_4;
+ NMIPConfig *ip_config_6;
+ NMIPConfig *ip_config_4;
};
NMIPConfig *ip_config_x[2];
};
- /* Config from DHCP, PPP, LLv4, etc */
- AppliedConfig dev_ip_config_4;
-
- /* config from the setting */
- union {
- struct {
- NMIP6Config *con_ip_config_6;
- NMIP4Config *con_ip_config_4;
- };
- NMIPConfig *con_ip_config_x[2];
- };
-
- /* Stuff added outside NM */
- union {
- struct {
- NMIP6Config *ext_ip_config_6;
- NMIP4Config *ext_ip_config_4;
- };
- NMIPConfig *ext_ip_config_x[2];
- };
-
- /* VPNs which use this device */
- union {
- struct {
- GSList *vpn_configs_6;
- GSList *vpn_configs_4;
- };
- GSList *vpn_configs_x[2];
- };
-
- /* Extra device configuration, injected by the subclass of NMDevice.
- * This is used for example by NMDeviceModem for WWAN configuration. */
- union {
- struct {
- AppliedConfig dev2_ip_config_6;
- AppliedConfig dev2_ip_config_4;
- };
- AppliedConfig dev2_ip_config_x[2];
- };
-
- /* DHCPv4 tracking */
struct {
- char *pac_url;
- } dhcp4;
-
- struct {
- /* IP6 config from DHCP */
- AppliedConfig ip6_config;
/* Event ID of the current IP6 config from DHCP */
- char * event_id;
gulong prefix_sigid;
NMNDiscDHCPLevel mode;
guint needed_prefixes;
@@ -588,24 +590,17 @@ typedef struct _NMDevicePrivate {
} gw_ping;
/* dnsmasq stuff for shared connections */
- NMDnsMasqManager *dnsmasq_manager;
- gulong dnsmasq_state_id;
+ NMDnsMasqManager *shared4_dnsmasq_manager;
+ gulong shared4_dnsmasq_state_id;
/* Firewall */
FirewallState fw_state : 4;
NMFirewalldManager * fw_mgr;
NMFirewalldManagerCallId *fw_call;
- /* IPv4LL stuff */
- sd_ipv4ll *ipv4ll;
- guint ipv4ll_timeout;
- guint rt6_temporary_not_available_id;
-
- /* IPv4 DAD stuff */
- struct {
- GSList * dad_list;
- NMAcdManager *announcing;
- } acd;
+ NML3IPv4LL * ll4_ipv4ll;
+ NML3IPv4LLRegistration *ll4_ipv4ll_registation;
+ guint ll4_timeout_id;
union {
struct {
@@ -618,17 +613,12 @@ typedef struct _NMDevicePrivate {
};
};
- AppliedConfig ac_ip6_config; /* config from IPv6 autoconfiguration */
- NMIP6Config * ext_ip6_config_captured; /* Configuration captured from platform. */
- NMIP6Config * dad6_ip6_config;
struct in6_addr ipv6ll_addr;
- GHashTable *rt6_temporary_not_available;
-
- NMNDisc * ndisc;
- gulong ndisc_changed_id;
- gulong ndisc_timeout_id;
- NMSettingIP6ConfigPrivacy ndisc_use_tempaddr;
+ NMNDisc * ac6_ndisc;
+ gulong ac6_ndisc_changed_id;
+ gulong ac6_ndisc_timeout_id;
+ NMSettingIP6ConfigPrivacy ac6_ip6_privacy;
guint linklocal6_timeout_id;
guint8 linklocal6_dad_counter;
@@ -703,59 +693,66 @@ G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
/*****************************************************************************/
+static NMSettingConnectionMdns _prop_get_connection_mdns(NMDevice *self);
+static NMSettingConnectionLlmnr _prop_get_connection_llmnr(NMDevice *self);
+
static const NMDBusInterfaceInfoExtended interface_info_device;
static const GDBusSignalInfo signal_info_state_changed;
-static void nm_device_set_proxy_config(NMDevice *self, const char *pac_url);
-
-static gboolean update_ext_ip_config(NMDevice *self, int addr_family, gboolean intersect_configs);
+static void _dev_l3_cfg_commit(NMDevice *self, gboolean commit_now);
-static gboolean nm_device_set_ip_config(NMDevice * self,
- int addr_family,
- NMIPConfig *config,
- gboolean commit,
- GPtrArray * ip4_dev_route_blacklist);
-
-static gboolean ip_config_merge_and_apply(NMDevice *self, int addr_family, gboolean commit);
+static void _dev_l3_cfg_commit_type_reset(NMDevice *self);
static gboolean nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure);
static void nm_device_slave_notify_enslave(NMDevice *self, gboolean success);
static void nm_device_slave_notify_release(NMDevice *self, NMDeviceStateReason reason);
-static void addrconf6_start_with_link_ready(NMDevice *self);
-static gboolean linklocal6_start(NMDevice *self);
+static gboolean _dev_ll6_start(NMDevice *self, struct in6_addr *out_ll_addr);
static guint32 default_route_metric_penalty_get(NMDevice *self, int addr_family);
static guint _prop_get_ipv4_dad_timeout(NMDevice *self);
-static NMIP6Config *dad6_get_pending_addresses(NMDevice *self);
-
static void _carrier_wait_check_queued_act_request(NMDevice *self);
static gint64 _get_carrier_wait_ms(NMDevice *self);
+static GBytes *_prop_get_ipv6_dhcp_duid(NMDevice * self,
+ NMConnection *connection,
+ GBytes * hwaddr,
+ gboolean * out_enforce);
+
static const char *_activation_func_to_string(ActivationHandleFunc func);
static void
_set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting);
-static void queued_state_clear(NMDevice *device);
-static gboolean queued_ip4_config_change(gpointer user_data);
-static gboolean queued_ip6_config_change(gpointer user_data);
-static void ip_check_ping_watch_cb(GPid pid, int status, gpointer user_data);
-static gboolean ip_config_valid(NMDeviceState state);
-static NMActStageReturn dhcp4_start(NMDevice *self);
-static gboolean dhcp6_start(NMDevice *self, gboolean wait_for_ll);
-static void nm_device_start_ip_check(NMDevice *self);
-static void realize_start_setup(NMDevice * self,
- const NMPlatformLink *plink,
- gboolean assume_state_guess_assume,
- const char * assume_state_connection_uuid,
- gboolean set_nm_owned,
- NMUnmanFlagOp unmanaged_user_explicit,
- gboolean force_platform_init);
-static void _set_mtu(NMDevice *self, guint32 mtu);
-static void _commit_mtu(NMDevice *self, const NMIP4Config *config);
-static void _cancel_activation(NMDevice *self);
+static void queued_state_clear(NMDevice *device);
+static void ip_check_ping_watch_cb(GPid pid, int status, gpointer user_data);
+static void nm_device_start_ip_check(NMDevice *self);
+static void realize_start_setup(NMDevice * self,
+ const NMPlatformLink *plink,
+ gboolean assume_state_guess_assume,
+ const char * assume_state_connection_uuid,
+ gboolean set_nm_owned,
+ NMUnmanFlagOp unmanaged_user_explicit,
+ gboolean force_platform_init);
+static void _set_mtu(NMDevice *self, guint32 mtu);
+static void _commit_mtu(NMDevice *self);
+static void _cancel_activation(NMDevice *self);
+
+static void _dev_ll4_notify_event(NMDevice *self);
+
+static void
+_dev_dhcpx_cleanup(NMDevice *self, int addr_family, gboolean reset_dhcp_config, gboolean release);
+
+static gboolean _dev_dhcpx_set_state(NMDevice *self, int addr_family, DhcpState state);
+
+static void _dev_dhcp4_notify_acd_result(NMDevice *self, gboolean ready);
+
+static gboolean _dev_ac6_start(NMDevice *self);
+
+static void _dev_set_unmanaged_external_down(NMDevice *self, gboolean only_if_unmanaged);
+
+static gboolean _dev_shared4_start(NMDevice *self, GError **error);
static void concheck_update_state(NMDevice * self,
int addr_family,
@@ -765,7 +762,7 @@ static void concheck_update_state(NMDevice * self,
static void sriov_op_cb(GError *error, gpointer user_data);
static void device_ifindex_changed_cb(NMManager *manager, NMDevice *device_changed, NMDevice *self);
-static gboolean device_link_changed(NMDevice *self);
+static gboolean device_link_changed(gpointer user_data);
/*****************************************************************************/
@@ -1326,8 +1323,8 @@ _prop_get_ipvx_dhcp_timeout(NMDevice *self, int addr_family)
{
NMDeviceClass *klass;
NMConnection * connection;
- int timeout_i;
guint32 timeout;
+ int timeout_i;
nm_assert(NM_IS_DEVICE(self));
nm_assert_addr_family(addr_family);
@@ -2369,27 +2366,6 @@ concheck_get_mgr(NMDevice *self)
return priv->concheck_mgr;
}
-NMIP4Config *
-nm_device_ip4_config_new(NMDevice *self)
-{
- return nm_ip4_config_new(nm_device_get_multi_index(self), nm_device_get_ip_ifindex(self));
-}
-
-NMIP6Config *
-nm_device_ip6_config_new(NMDevice *self)
-{
- return nm_ip6_config_new(nm_device_get_multi_index(self), nm_device_get_ip_ifindex(self));
-}
-
-NMIPConfig *
-nm_device_ip_config_new(NMDevice *self, int addr_family)
-{
- nm_assert_addr_family(addr_family);
-
- return NM_IS_IPv4(addr_family) ? (gpointer) nm_device_ip4_config_new(self)
- : (gpointer) nm_device_ip6_config_new(self);
-}
-
NML3ConfigData *
nm_device_create_l3_config_data(NMDevice *self)
{
@@ -2404,98 +2380,33 @@ nm_device_create_l3_config_data(NMDevice *self)
return nm_l3_config_data_new(nm_device_get_multi_index(self), ifindex);
}
-static void
-applied_config_clear(AppliedConfig *config)
-{
- g_clear_object(&config->current);
- g_clear_object(&config->orig);
-}
-
-static void
-applied_config_init(AppliedConfig *config, gpointer ip_config)
-{
- nm_assert(!ip_config || (!config->orig && !config->current)
- || nm_ip_config_get_addr_family(ip_config)
- == nm_ip_config_get_addr_family(config->orig ?: config->current));
- nm_assert(!ip_config || NM_IS_IP_CONFIG(ip_config));
-
- nm_g_object_ref(ip_config);
- applied_config_clear(config);
- config->orig = ip_config;
-}
-
-static void
-applied_config_init_new(AppliedConfig *config, NMDevice *self, int addr_family)
-{
- gs_unref_object NMIPConfig *c = nm_device_ip_config_new(self, addr_family);
-
- applied_config_init(config, c);
-}
-
-static NMIPConfig *
-applied_config_get_current(AppliedConfig *config)
-{
- return config->current ?: config->orig;
-}
-
-static void
-applied_config_add_address(AppliedConfig *config, const NMPlatformIPAddress *address)
+static const NML3ConfigData *
+_dev_create_l3_config_data_from_connection(NMDevice *self, NMConnection *connection)
{
- if (config->orig)
- nm_ip_config_add_address(config->orig, address);
- else
- nm_assert(!config->current);
-
- if (config->current)
- nm_ip_config_add_address(config->current, address);
-}
-
-static void
-applied_config_add_nameserver(AppliedConfig *config, const NMIPAddr *ns)
-{
- if (config->orig)
- nm_ip_config_add_nameserver(config->orig, ns);
- else
- nm_assert(!config->current);
-
- if (config->current)
- nm_ip_config_add_nameserver(config->current, ns);
-}
-
-static void
-applied_config_add_search(AppliedConfig *config, const char *new)
-{
- if (config->orig)
- nm_ip_config_add_search(config->orig, new);
- else
- nm_assert(!config->current);
+ NML3ConfigData *l3cd;
+ int ifindex;
- if (config->current)
- nm_ip_config_add_search(config->current, new);
-}
-
-static void
-applied_config_reset_searches(AppliedConfig *config)
-{
- if (config->orig)
- nm_ip_config_reset_searches(config->orig);
- else
- nm_assert(!config->current);
+ nm_assert(NM_IS_DEVICE(self));
+ nm_assert(!connection || NM_IS_CONNECTION(self));
- if (config->current)
- nm_ip_config_reset_searches(config->current);
-}
+ if (!connection)
+ return NULL;
-static void
-applied_config_reset_nameservers(AppliedConfig *config)
-{
- if (config->orig)
- nm_ip_config_reset_nameservers(config->orig);
- else
- nm_assert(!config->current);
+ ifindex = nm_device_get_ip_ifindex(self);
+ if (ifindex <= 0)
+ g_return_val_if_reached(NULL);
- if (config->current)
- nm_ip_config_reset_nameservers(config->current);
+ l3cd = nm_l3_config_data_new_from_connection(nm_device_get_multi_index(self),
+ ifindex,
+ connection,
+ nm_device_get_route_table(self, AF_INET),
+ nm_device_get_route_table(self, AF_INET6),
+ nm_device_get_route_metric(self, AF_INET),
+ nm_device_get_route_metric(self, AF_INET6));
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_USER);
+ nm_l3_config_data_set_mdns(l3cd, _prop_get_connection_mdns(self));
+ nm_l3_config_data_set_llmnr(l3cd, _prop_get_connection_llmnr(self));
+ return nm_l3_config_data_seal(l3cd);
}
/*****************************************************************************/
@@ -2541,6 +2452,7 @@ nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_st
nm_device_sys_iface_state_to_str(priv->sys_iface_state),
nm_device_sys_iface_state_to_str(sys_iface_state));
priv->sys_iface_state_ = sys_iface_state;
+ _dev_l3_cfg_commit_type_reset(self);
}
/* this function only sets a flag, no immediate actions are initiated.
@@ -2653,33 +2565,6 @@ nm_device_assume_state_reset(NMDevice *self)
/*****************************************************************************/
-static void
-init_ip_config_dns_priority(NMDevice *self, NMIPConfig *config)
-{
- const char *property;
- int priority;
-
- property = (nm_ip_config_get_addr_family(config) == AF_INET)
- ? NM_CON_DEFAULT("ipv4.dns-priority")
- : NM_CON_DEFAULT("ipv6.dns-priority");
-
- priority = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
- property,
- self,
- G_MININT,
- G_MAXINT,
- 0);
-
- if (priority == 0) {
- priority =
- nm_device_is_vpn(self) ? NM_DNS_PRIORITY_DEFAULT_VPN : NM_DNS_PRIORITY_DEFAULT_NORMAL;
- }
-
- nm_ip_config_set_dns_priority(config, priority);
-}
-
-/*****************************************************************************/
-
static char *
nm_device_sysctl_ip_conf_get(NMDevice *self, int addr_family, const char *property)
{
@@ -2847,6 +2732,496 @@ _set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state)
}
}
+static void
+_set_ip_state_check(NMDevice *self, int addr_family)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ int IS_IPv4;
+
+ if (addr_family == AF_UNSPEC) {
+ _set_ip_state_check(self, AF_INET);
+ _set_ip_state_check(self, AF_INET6);
+ return;
+ }
+
+ IS_IPv4 = NM_IS_IPv4(addr_family);
+
+ if (IS_IPv4) {
+ //XXX
+ AddrMethodState addr_method_state_dhcp_4 = ADDR_METHOD_STATE_DISABLED;
+
+ if (priv->dhcp_data_4.client) {
+ /* DHCP is enabled. */
+ if (priv->dhcp_data_4.grace_source) {
+ /* we are still waiting for DHCP to complete/succeed. */
+ addr_method_state_dhcp_4 = ADDR_METHOD_STATE_PENDING;
+ }
+ //XXX } else if (priv->dhcp_data_4.is_bad || !priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_4].d) {
+ //XXX /* the DHCP configuration is failed. */
+ //XXX addr_method_state_dhcp_4 = ADDR_METHOD_STATE_FAILED;
+ //XXX } else
+ //XXX addr_method_state_dhcp_4 = ADDR_METHOD_STATE_GOOD;
+ }
+
+ (void) addr_method_state_dhcp_4;
+ }
+
+ // FIXME(l3cfg): need to check the current state and derive an overall _set_ip_state() value.
+
+ // FIXME(l3cfg): check for IPv6 addresses in DAD with nm_l3cfg_has_commited_ip6_addresses_pending_dad().
+}
+
+/*****************************************************************************/
+
+static gpointer
+_dev_l3_config_data_tag_get(NMDevicePrivate *priv, L3ConfigDataType l3cd_type)
+{
+ nm_assert(_NM_INT_NOT_NEGATIVE(l3cd_type) && l3cd_type < G_N_ELEMENTS(priv->l3cds));
+
+ return &priv->l3cds[l3cd_type];
+}
+
+static L3ConfigDataType
+_dev_l3_config_data_tag_to_type(NMDevice *self, gconstpointer tag)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ int d;
+
+ /* In C it is undefined behavior to compare unrelated pointers.
+ * Work around that by using nm_ptr_to_uintptr(), which casts the pointers
+ * to integers.
+ *
+ * I guess, theoretically it's still a problem to assume that if tag pointers
+ * somewhere inside priv->l3cds, that the uintptr_t case would also yield
+ * a value in that range. In practice, I couldn't imaging this not not work
+ * reliably. */
+
+ if (nm_ptr_to_uintptr(tag) < nm_ptr_to_uintptr(&priv->l3cds[0])
+ || nm_ptr_to_uintptr(tag) >= nm_ptr_to_uintptr(&priv->l3cds[G_N_ELEMENTS(priv->l3cds)]))
+ return _L3_CONFIG_DATA_TYPE_NONE;
+
+ d = ((typeof(priv->l3cds[0]) *) tag) - (&priv->l3cds[0]);
+
+ nm_assert(d >= 0);
+ nm_assert(d < _L3_CONFIG_DATA_TYPE_NUM);
+ nm_assert(tag == &priv->l3cds[d]);
+ nm_assert(tag == _dev_l3_config_data_tag_get(priv, d));
+ return d;
+}
+
+static L3ConfigDataType
+_dev_l3_config_data_acd_addr_info_to_type(NMDevice * self,
+ const NML3AcdAddrInfo *addr_info,
+ guint i_track_infos)
+{
+ nm_assert(NM_IS_DEVICE(self));
+ nm_assert(addr_info);
+ nm_assert(i_track_infos < addr_info->n_track_infos);
+
+ return _dev_l3_config_data_tag_to_type(self, addr_info->track_infos[i_track_infos].tag);
+}
+
+static gboolean
+_dev_l3_config_data_acd_addr_info_has(NMDevice * self,
+ const NML3AcdAddrInfo *addr_info,
+ L3ConfigDataType l3cd_type)
+{
+ guint i;
+
+ nm_assert(NM_IS_DEVICE(self));
+ nm_assert(addr_info);
+ nm_assert(_NM_INT_NOT_NEGATIVE(l3cd_type) && l3cd_type < _L3_CONFIG_DATA_TYPE_NUM);
+
+ for (i = 0; i < addr_info->n_track_infos; i++) {
+ if (l3cd_type == _dev_l3_config_data_acd_addr_info_to_type(self, addr_info, i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+_dev_l3_get_config_settings(NMDevice * self,
+ L3ConfigDataType type,
+ NML3ConfigMergeFlags *out_merge_flags,
+ NML3AcdDefendType * out_acd_defend_type,
+ guint32 * out_acd_timeout_msec)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NML3ConfigMergeFlags flags;
+ NMConnection * connection;
+ NMSettingIPConfig * s_ip;
+
+ nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < _L3_CONFIG_DATA_TYPE_NUM);
+
+ if (G_UNLIKELY(!priv->l3config_merge_flags_has)) {
+ int IS_IPv4;
+
+ connection = nm_device_get_applied_connection(self);
+
+ for (IS_IPv4 = 0; IS_IPv4 < 2; IS_IPv4++) {
+ flags = NM_L3_CONFIG_MERGE_FLAGS_NONE;
+
+ if (connection
+ && (s_ip = nm_connection_get_setting_ip_config(connection,
+ IS_IPv4 ? AF_INET : AF_INET6))) {
+ if (nm_setting_ip_config_get_ignore_auto_routes(s_ip))
+ flags |= NM_L3_CONFIG_MERGE_FLAGS_NO_ROUTES;
+
+ if (nm_setting_ip_config_get_ignore_auto_dns(s_ip))
+ flags |= NM_L3_CONFIG_MERGE_FLAGS_NO_DNS;
+
+ if (nm_setting_ip_config_get_never_default(s_ip)
+ || nm_setting_ip_config_get_gateway(s_ip)) {
+ /* if the connection has an explicit gateway, we also ignore
+ * the default routes from other sources. */
+ flags |= NM_L3_CONFIG_MERGE_FLAGS_NO_DEFAULT_ROUTES;
+ }
+ }
+
+ priv->l3config_merge_flags_x[IS_IPv4] = flags;
+ }
+ priv->l3config_merge_flags_has = TRUE;
+ }
+
+ switch (type) {
+ case L3_CONFIG_DATA_TYPE_SETTING:
+ case L3_CONFIG_DATA_TYPE_LL_4:
+ case L3_CONFIG_DATA_TYPE_LL_6:
+ case L3_CONFIG_DATA_TYPE_PD_6:
+ case L3_CONFIG_DATA_TYPE_SHARED_4:
+ case L3_CONFIG_DATA_TYPE_DHCP_4:
+ case L3_CONFIG_DATA_TYPE_DEV_4:
+ case L3_CONFIG_DATA_TYPE_AC_6:
+ case L3_CONFIG_DATA_TYPE_DHCP_6:
+ case L3_CONFIG_DATA_TYPE_DEV_6:
+ *out_acd_timeout_msec = _prop_get_ipv4_dad_timeout(self);
+ break;
+
+ case _L3_CONFIG_DATA_TYPE_NUM:
+ case _L3_CONFIG_DATA_TYPE_NONE:
+ *out_acd_timeout_msec = nm_assert_unreachable_val(0);
+ break;
+ }
+
+ switch (type) {
+ case L3_CONFIG_DATA_TYPE_LL_4:
+ *out_acd_defend_type = NM_L3_ACD_DEFEND_TYPE_ONCE;
+ break;
+
+ case L3_CONFIG_DATA_TYPE_SETTING:
+ case L3_CONFIG_DATA_TYPE_LL_6:
+ case L3_CONFIG_DATA_TYPE_PD_6:
+ case L3_CONFIG_DATA_TYPE_SHARED_4:
+ case L3_CONFIG_DATA_TYPE_DHCP_4:
+ case L3_CONFIG_DATA_TYPE_DEV_4:
+ case L3_CONFIG_DATA_TYPE_AC_6:
+ case L3_CONFIG_DATA_TYPE_DHCP_6:
+ case L3_CONFIG_DATA_TYPE_DEV_6:
+ *out_acd_defend_type = NM_L3_ACD_DEFEND_TYPE_ALWAYS;
+ break;
+
+ case _L3_CONFIG_DATA_TYPE_NUM:
+ case _L3_CONFIG_DATA_TYPE_NONE:
+ *out_acd_defend_type = nm_assert_unreachable_val(NM_L3_ACD_DEFEND_TYPE_ALWAYS);
+ break;
+ }
+
+ switch (type) {
+ case L3_CONFIG_DATA_TYPE_SETTING:
+ case L3_CONFIG_DATA_TYPE_LL_4:
+ case L3_CONFIG_DATA_TYPE_LL_6:
+ case L3_CONFIG_DATA_TYPE_PD_6:
+ case L3_CONFIG_DATA_TYPE_SHARED_4:
+ *out_merge_flags = NM_L3_CONFIG_MERGE_FLAGS_NONE;
+ break;
+
+ case L3_CONFIG_DATA_TYPE_DHCP_4:
+ case L3_CONFIG_DATA_TYPE_DEV_4:
+ *out_merge_flags = priv->l3config_merge_flags_4;
+ break;
+
+ case L3_CONFIG_DATA_TYPE_AC_6:
+ case L3_CONFIG_DATA_TYPE_DHCP_6:
+ case L3_CONFIG_DATA_TYPE_DEV_6:
+ *out_merge_flags = priv->l3config_merge_flags_6;
+ break;
+
+ case _L3_CONFIG_DATA_TYPE_NUM:
+ case _L3_CONFIG_DATA_TYPE_NONE:
+ *out_merge_flags = nm_assert_unreachable_val(NM_L3_CONFIG_MERGE_FLAGS_NONE);
+ break;
+ }
+}
+
+static gboolean
+_dev_l3_register_l3cds_add_config(NMDevice *self, L3ConfigDataType l3cd_type)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NML3ConfigMergeFlags merge_flags;
+ NML3AcdDefendType acd_defend_type;
+ guint32 acd_timeout_msec;
+
+ _dev_l3_get_config_settings(self, l3cd_type, &merge_flags, &acd_defend_type, &acd_timeout_msec);
+ return nm_l3cfg_add_config(priv->l3cfg,
+ _dev_l3_config_data_tag_get(priv, l3cd_type),
+ FALSE,
+ priv->l3cds[l3cd_type].d,
+ l3cd_type,
+ nm_device_get_route_table(self, AF_INET),
+ nm_device_get_route_table(self, AF_INET6),
+ nm_device_get_route_metric(self, AF_INET),
+ nm_device_get_route_metric(self, AF_INET6),
+ default_route_metric_penalty_get(self, AF_INET),
+ default_route_metric_penalty_get(self, AF_INET6),
+ acd_defend_type,
+ acd_timeout_msec,
+ merge_flags);
+}
+
+static gboolean
+_dev_l3_register_l3cds_set_one(NMDevice * self,
+ L3ConfigDataType l3cd_type,
+ const NML3ConfigData *l3cd,
+ NMTernary commit_sync)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_old = NULL;
+ gboolean changed = FALSE;
+
+ if (priv->l3cds[l3cd_type].d != l3cd) {
+ l3cd_old = g_steal_pointer(&priv->l3cds[l3cd_type].d);
+ if (l3cd)
+ priv->l3cds[l3cd_type].d = nm_l3_config_data_ref_and_seal(l3cd);
+ }
+
+ if (priv->l3cfg) {
+ if (priv->l3cds[l3cd_type].d) {
+ if (_dev_l3_register_l3cds_add_config(self, l3cd_type))
+ changed = TRUE;
+ }
+
+ if (l3cd_old && l3cd_old != priv->l3cds[l3cd_type].d) {
+ if (nm_l3cfg_remove_config(priv->l3cfg,
+ _dev_l3_config_data_tag_get(priv, l3cd_type),
+ l3cd_old))
+ changed = TRUE;
+ }
+ }
+
+ if (changed && commit_sync != NM_TERNARY_DEFAULT)
+ _dev_l3_cfg_commit(self, !!commit_sync);
+
+ return changed;
+}
+
+static gboolean
+_dev_l3_register_l3cds(NMDevice *self,
+ NML3Cfg * l3cfg,
+ gboolean do_add /* else remove */,
+ NMTernary do_commit)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ gboolean is_external;
+ gboolean changed;
+ int i;
+
+ if (!l3cfg)
+ return FALSE;
+
+ is_external = nm_device_sys_iface_state_is_external(self);
+
+ changed = FALSE;
+ for (i = 0; i < (int) G_N_ELEMENTS(priv->l3cds); i++) {
+ if (!priv->l3cds[i].d)
+ continue;
+ if (!do_add) {
+ if (nm_l3cfg_remove_config(l3cfg,
+ _dev_l3_config_data_tag_get(priv, i),
+ priv->l3cds[i].d))
+ changed = TRUE;
+ continue;
+ }
+ if (is_external)
+ continue;
+ if (_dev_l3_register_l3cds_add_config(self, i))
+ changed = TRUE;
+ }
+
+ if (do_commit == NM_TERNARY_DEFAULT)
+ do_commit = changed;
+ if (do_commit)
+ _dev_l3_cfg_commit(self, TRUE);
+
+ return changed;
+}
+
+/*****************************************************************************/
+
+static void
+_dev_l3_notify_change(NMDevice *self, int addr_family)
+{
+ /* FIXME(l3cfg) */
+ nm_device_activate_schedule_ip_config_result(self, addr_family);
+}
+
+static void
+_dev_l3_cfg_commit(NMDevice *self, gboolean commit_sync)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+
+ if (!priv->l3cfg)
+ return;
+
+ if (!commit_sync) {
+ nm_l3cfg_commit_on_idle_schedule(priv->l3cfg);
+ return;
+ }
+ nm_l3cfg_commit(priv->l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO);
+}
+
+static void
+_dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+
+ nm_assert(l3cfg == priv->l3cfg);
+
+ /* FIXME(l3cfg) */
+ switch (notify_data->notify_type) {
+ case NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED:
+ if (notify_data->l3cd_changed.commited) {
+ g_signal_emit(self,
+ signals[L3CD_CHANGED],
+ 0,
+ notify_data->l3cd_changed.l3cd_old,
+ notify_data->l3cd_changed.l3cd_new);
+ }
+ return;
+ case NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT:
+ {
+ const NML3AcdAddrInfo *addr_info = &notify_data->acd_event.info;
+ gboolean has_dhcp_4;
+
+ if (addr_info->state <= NM_L3_ACD_ADDR_STATE_PROBING) {
+ /* still probing... */
+ return;
+ }
+
+ has_dhcp_4 =
+ _dev_l3_config_data_acd_addr_info_has(self, addr_info, L3_CONFIG_DATA_TYPE_DHCP_4);
+ if (has_dhcp_4) {
+ if (addr_info->state <= NM_L3_ACD_ADDR_STATE_USED)
+ _dev_dhcp4_notify_acd_result(self, FALSE);
+ else
+ _dev_dhcp4_notify_acd_result(self, TRUE);
+ return;
+ }
+
+ /* other types for ACD results for non-DHCPv4 sources we currently ignore. */
+ return;
+ }
+ case NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT:
+ /* FIXME(l3cfg) */
+ _dev_l3_notify_change(self, AF_INET);
+ return;
+ case NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT:
+ if (priv->ll4_ipv4ll == notify_data->ipv4ll_event.ipv4ll)
+ _dev_ll4_notify_event(self);
+ return;
+ case NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE:
+ case NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED:
+ /* FIXME(l3cfg) */
+ return;
+ case NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE:
+ if (NM_FLAGS_ANY(notify_data->platform_change_on_idle.obj_type_flags,
+ nmp_object_type_to_flags(NMP_OBJECT_TYPE_IP4_ADDRESS)
+ | nmp_object_type_to_flags(NMP_OBJECT_TYPE_IP4_ROUTE)))
+ _dev_l3_notify_change(self, AF_INET);
+ if (NM_FLAGS_ANY(notify_data->platform_change_on_idle.obj_type_flags,
+ nmp_object_type_to_flags(NMP_OBJECT_TYPE_IP6_ADDRESS)
+ | nmp_object_type_to_flags(NMP_OBJECT_TYPE_IP6_ROUTE)))
+ _dev_l3_notify_change(self, AF_INET6);
+
+ _dev_set_unmanaged_external_down(self, TRUE);
+ return;
+ case _NM_L3_CONFIG_NOTIFY_TYPE_NUM:
+ break;
+ }
+ nm_assert_not_reached();
+}
+
+static void
+_dev_l3_cfg_commit_type_reset(NMDevice *self)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NML3CfgCommitType commit_type;
+
+ if (!priv->l3cfg)
+ return;
+
+ switch (priv->sys_iface_state) {
+ case NM_DEVICE_SYS_IFACE_STATE_EXTERNAL:
+ case NM_DEVICE_SYS_IFACE_STATE_REMOVED:
+ commit_type = NM_L3_CFG_COMMIT_TYPE_NONE;
+ goto do_set;
+ case NM_DEVICE_SYS_IFACE_STATE_ASSUME:
+ commit_type = NM_L3_CFG_COMMIT_TYPE_ASSUME;
+ goto do_set;
+ case NM_DEVICE_SYS_IFACE_STATE_MANAGED:
+ commit_type = NM_L3_CFG_COMMIT_TYPE_UPDATE;
+ goto do_set;
+ }
+ nm_assert_not_reached();
+ return;
+
+do_set:
+ priv->l3cfg_commit_type =
+ nm_l3cfg_commit_type_register(priv->l3cfg, commit_type, priv->l3cfg_commit_type);
+}
+
+/*****************************************************************************/
+
+//XXX FIXME(l3cfg)
+_nm_unused static gboolean
+_dev_l3_set_l3cd_setting(NMDevice *self)
+{
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+
+ l3cd = _dev_create_l3_config_data_from_connection(self, nm_device_get_applied_connection(self));
+ return _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_SETTING, l3cd, FALSE);
+}
+
+static gboolean
+_dev_l3_set_l3cd_ll_6(NMDevice *self)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+
+ if (priv->ipv6ll_has) {
+ const NMPlatformIP6Address ll_a = {
+ .address = priv->ipv6ll_addr,
+ .plen = 64,
+ .addr_source = NM_IP_CONFIG_SOURCE_IP6LL,
+ };
+ const NMPlatformIP6Route ll_r = {
+ .network.s6_addr16[0] = htons(0xfe80u),
+ .plen = 64,
+ .metric = nm_device_get_route_metric(self, AF_INET6),
+ .rt_source = NM_IP_CONFIG_SOURCE_IP6LL,
+ };
+
+ nm_assert(IN6_IS_ADDR_LINKLOCAL(&priv->ipv6ll_addr));
+
+ l3cd = nm_device_create_l3_config_data(self);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_IP6LL);
+ nm_l3_config_data_add_address_6(l3cd, &ll_a);
+ nm_l3_config_data_add_route_6(l3cd, &ll_r);
+ nm_l3_config_data_seal(l3cd);
+ }
+
+ return _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_LL_6, l3cd, FALSE);
+}
+
/*****************************************************************************/
const char *
@@ -2868,11 +3243,18 @@ nm_device_get_iface(NMDevice *self)
static gboolean
_set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- int * p_ifindex;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ gs_unref_object NML3Cfg *l3cfg_old = NULL;
+ NML3CfgCommitTypeHandle *l3cfg_commit_type_old = NULL;
+ gboolean l3_changed;
+ int ip_ifindex_new;
+ int * p_ifindex;
+ gboolean l3cfg_was_reset = FALSE;
- if (ifindex < 0)
+ if (ifindex < 0) {
+ nm_assert_not_reached();
ifindex = 0;
+ }
p_ifindex = is_ip_ifindex ? &priv->ip_ifindex_ : &priv->ifindex_;
@@ -2881,13 +3263,74 @@ _set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex)
*p_ifindex = ifindex;
- _LOGD(LOGD_DEVICE, "ifindex: set %sifindex %d", is_ip_ifindex ? "ip-" : "", ifindex);
+ ip_ifindex_new = nm_device_get_ip_ifindex(self);
- if (!is_ip_ifindex)
- _notify(self, PROP_IFINDEX);
+ if (priv->l3cfg) {
+ if (ip_ifindex_new <= 0 || ip_ifindex_new != nm_l3cfg_get_ifindex(priv->l3cfg)) {
+ g_signal_handlers_disconnect_by_func(priv->l3cfg,
+ G_CALLBACK(_dev_l3_cfg_notify_cb),
+ self);
+ l3cfg_old = g_steal_pointer(&priv->l3cfg_);
+ l3cfg_commit_type_old = g_steal_pointer(&priv->l3cfg_commit_type);
+ l3cfg_was_reset = TRUE;
+ }
+ }
+ if (!priv->l3cfg && ip_ifindex_new > 0) {
+ priv->l3cfg_ = nm_netns_access_l3cfg(priv->netns, ip_ifindex_new);
+
+ g_signal_connect(priv->l3cfg,
+ NM_L3CFG_SIGNAL_NOTIFY,
+ G_CALLBACK(_dev_l3_cfg_notify_cb),
+ self);
+
+ _dev_l3_cfg_commit_type_reset(self);
+ l3cfg_was_reset = TRUE;
+ }
+
+ _LOGD(LOGD_DEVICE,
+ "ifindex: set %sifindex %d%s%s%s%s%s%s",
+ is_ip_ifindex ? "ip-" : "",
+ ifindex,
+ NM_PRINT_FMT_QUOTED(l3cfg_old && l3cfg_old != priv->l3cfg,
+ " (old-l3cfg: ",
+ nm_hash_obfuscated_ptr_str_a(l3cfg_old),
+ ")",
+ ""),
+ NM_PRINT_FMT_QUOTED(priv->l3cfg && l3cfg_old != priv->l3cfg,
+ " (l3cfg: ",
+ nm_hash_obfuscated_ptr_str_a(priv->l3cfg),
+ ")",
+ ""));
if (priv->manager)
nm_manager_emit_device_ifindex_changed(priv->manager, self);
+
+ if (!is_ip_ifindex)
+ _notify(self, PROP_IFINDEX);
+
+ if (l3cfg_was_reset) {
+ nm_ip_config_take_and_unexport_on_idle(g_steal_pointer(&priv->ip_config_4));
+ nm_ip_config_take_and_unexport_on_idle(g_steal_pointer(&priv->ip_config_6));
+ if (priv->l3cfg) {
+ priv->ip_config_4 = nm_ip_config_new(AF_INET, priv->l3cfg, FALSE);
+ priv->ip_config_6 = nm_ip_config_new(AF_INET6, priv->l3cfg, FALSE);
+ }
+ _notify(self, PROP_IP4_CONFIG);
+ _notify(self, PROP_IP6_CONFIG);
+ }
+
+ l3_changed = FALSE;
+ if (_dev_l3_register_l3cds(self, priv->l3cfg, TRUE, FALSE))
+ l3_changed = TRUE;
+ if (_dev_l3_register_l3cds(self, l3cfg_old, FALSE, FALSE))
+ l3_changed = TRUE;
+
+ if (l3_changed)
+ _dev_l3_cfg_commit(self, TRUE);
+
+ if (l3cfg_commit_type_old)
+ nm_l3cfg_commit_type_unregister(l3cfg_old, l3cfg_commit_type_old);
+
return TRUE;
}
@@ -3623,7 +4066,8 @@ nm_device_get_route_metric_default(NMDeviceType device_type)
return 11000;
}
-static gboolean
+//XXX FIXME(l3cfg)
+_nm_unused static gboolean
default_route_metric_penalty_detect(NMDevice *self, int addr_family)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
@@ -3707,28 +4151,22 @@ nm_device_get_route_table(NMDevice *self, int addr_family)
return route_table ?: (guint32) RT_TABLE_MAIN;
}
-static NMIPRouteTableSyncMode
+//XXX
+_nm_unused static NMIPRouteTableSyncMode
_get_route_table_sync_mode_stateful(NMDevice *self, int addr_family)
{
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMDedupMultiIter ipconf_iter;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
gboolean all_sync_now;
gboolean all_sync_eff;
all_sync_now = _prop_get_ipvx_route_table(self, addr_family) != 0u;
if (!all_sync_now) {
- const NMPlatformIPRoute *route;
+ const NML3ConfigData *l3cd = priv->l3cds[L3_CONFIG_DATA_TYPE_SETTING].d;
/* If there's a local route switch to all-sync in order
* to properly manage the local table */
- nm_ip_config_iter_ip_route_for_each (&ipconf_iter, priv->con_ip_config_x[IS_IPv4], &route) {
- if (nm_platform_route_type_uncoerce(route->type_coerced) == RTN_LOCAL) {
- all_sync_now = TRUE;
- break;
- }
- }
+ all_sync_now = l3cd && nm_l3_config_data_has_routes_with_type_local(l3cd, addr_family);
}
if (all_sync_now)
@@ -3760,18 +4198,10 @@ nm_device_get_best_default_route(NMDevice *self, int addr_family)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- switch (addr_family) {
- case AF_INET:
- return priv->ip_config_4 ? nm_ip4_config_best_default_route_get(priv->ip_config_4) : NULL;
- case AF_INET6:
- return priv->ip_config_6 ? nm_ip6_config_best_default_route_get(priv->ip_config_6) : NULL;
- case AF_UNSPEC:
- return (priv->ip_config_4 ? nm_ip4_config_best_default_route_get(priv->ip_config_4) : NULL)
- ?: (priv->ip_config_6 ? nm_ip6_config_best_default_route_get(priv->ip_config_6)
- : NULL);
- default:
- g_return_val_if_reached(NULL);
- }
+ if (!priv->l3cfg)
+ return NULL;
+
+ return nm_l3cfg_get_best_default_route(priv->l3cfg, addr_family, TRUE);
}
const char *
@@ -4326,14 +4756,8 @@ concheck_update_state(NMDevice * self,
_notify(self, IS_IPv4 ? PROP_IP4_CONNECTIVITY : PROP_IP6_CONNECTIVITY);
- if (priv->state == NM_DEVICE_STATE_ACTIVATED && !nm_device_sys_iface_state_is_external(self)) {
- if (nm_device_get_best_default_route(self, AF_INET)
- && !ip_config_merge_and_apply(self, AF_INET, TRUE))
- _LOGW(LOGD_IP4, "Failed to update IPv4 route metric");
- if (nm_device_get_best_default_route(self, AF_INET6)
- && !ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "Failed to update IPv6 route metric");
- }
+ if (priv->state == NM_DEVICE_STATE_ACTIVATED && !nm_device_sys_iface_state_is_external(self))
+ _dev_l3_register_l3cds(self, priv->l3cfg, AF_UNSPEC, NM_TERNARY_DEFAULT);
}
static const char *
@@ -4700,10 +5124,6 @@ nm_device_master_enslave_slave(NMDevice *self, NMDevice *slave, NMConnection *co
*/
nm_device_update_hw_address(self);
- /* Send ARP announcements if did not yet and have addresses. */
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && !priv->acd.announcing)
- nm_device_arp_announce(self);
-
/* Restart IP configuration if we're waiting for slaves. Do this
* after updating the hardware address as IP config may need the
* new address.
@@ -4719,7 +5139,7 @@ nm_device_master_enslave_slave(NMDevice *self, NMDevice *slave, NMConnection *co
/* Since slave devices don't have their own IP configuration,
* set the MTU here.
*/
- _commit_mtu(slave, NM_DEVICE_GET_PRIVATE(slave)->ip_config_4);
+ _commit_mtu(slave);
return success;
}
@@ -4837,7 +5257,7 @@ is_unmanaged_external_down(NMDevice *self, gboolean consider_can)
}
static void
-set_unmanaged_external_down(NMDevice *self, gboolean only_if_unmanaged)
+_dev_set_unmanaged_external_down(NMDevice *self, gboolean only_if_unmanaged)
{
NMUnmanFlagOp ext_flags;
@@ -4877,26 +5297,26 @@ nm_device_update_dynamic_ip_setup(NMDevice *self)
g_hash_table_remove_all(priv->ip6_saved_properties);
- if (priv->dhcp_data_4.client) {
- if (!nm_device_dhcp4_renew(self, FALSE)) {
+ if (priv->dhcp_data_4.state != DHCP_STATE_NONE) {
+ if (!nm_device_dhcp_renew(self, AF_INET, FALSE)) {
nm_device_state_changed(self,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_DHCP_FAILED);
return;
}
}
- if (priv->dhcp_data_6.client) {
- if (!nm_device_dhcp6_renew(self, FALSE)) {
+ if (priv->dhcp_data_6.state != DHCP_STATE_NONE) {
+ if (!nm_device_dhcp_renew(self, AF_INET6, FALSE)) {
nm_device_state_changed(self,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_DHCP_FAILED);
return;
}
}
- if (priv->ndisc) {
+ if (priv->ac6_ndisc) {
/* FIXME: todo */
}
- if (priv->dnsmasq_manager) {
+ if (priv->shared4_dnsmasq_manager) {
/* FIXME: todo */
}
}
@@ -5163,82 +5583,20 @@ device_ifindex_changed_cb(NMManager *manager, NMDevice *device_changed, NMDevice
}
static void
-ndisc_set_router_config(NMNDisc *ndisc, NMDevice *self)
+_dev_ac6_ndisc_set_router_config(NMDevice *self)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- gs_unref_array GArray *addresses = NULL;
- gs_unref_array GArray *dns_servers = NULL;
- gs_unref_array GArray * dns_domains = NULL;
- guint len;
- guint i;
- const NMDedupMultiHeadEntry *head_entry;
- NMDedupMultiIter ipconf_iter;
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ const NML3ConfigData *l3cd;
- if (nm_ndisc_get_node_type(ndisc) != NM_NDISC_NODE_TYPE_ROUTER)
+ if (!priv->ac6_ndisc)
return;
- head_entry = nm_ip6_config_lookup_addresses(priv->ip_config_6);
- addresses =
- g_array_sized_new(FALSE, TRUE, sizeof(NMNDiscAddress), head_entry ? head_entry->len : 0);
- nm_dedup_multi_iter_for_each (&ipconf_iter, head_entry) {
- const NMPlatformIP6Address *addr = NMP_OBJECT_CAST_IP6_ADDRESS(ipconf_iter.current->obj);
- NMNDiscAddress * ndisc_addr;
- guint32 lifetime;
- guint32 preferred;
-
- if (IN6_IS_ADDR_UNSPECIFIED(&addr->address) || IN6_IS_ADDR_LINKLOCAL(&addr->address))
- continue;
-
- if (addr->n_ifa_flags & IFA_F_TENTATIVE || addr->n_ifa_flags & IFA_F_DADFAILED)
- continue;
-
- if (addr->plen != 64)
- continue;
-
- lifetime = nmp_utils_lifetime_get(addr->timestamp,
- addr->lifetime,
- addr->preferred,
- NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000,
- &preferred);
- if (!lifetime)
- continue;
-
- g_array_set_size(addresses, addresses->len + 1);
- ndisc_addr = &g_array_index(addresses, NMNDiscAddress, addresses->len - 1);
- ndisc_addr->address = addr->address;
- ndisc_addr->expiry_msec =
- _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, lifetime);
- ndisc_addr->expiry_preferred_msec =
- _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, preferred);
- }
-
- len = nm_ip6_config_get_num_nameservers(priv->ip_config_6);
- dns_servers = g_array_sized_new(FALSE, TRUE, sizeof(NMNDiscDNSServer), len);
- g_array_set_size(dns_servers, len);
- for (i = 0; i < len; i++) {
- const struct in6_addr *nameserver = nm_ip6_config_get_nameserver(priv->ip_config_6, i);
- NMNDiscDNSServer * ndisc_nameserver;
-
- ndisc_nameserver = &g_array_index(dns_servers, NMNDiscDNSServer, i);
- ndisc_nameserver->address = *nameserver;
- ndisc_nameserver->expiry_msec =
- _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, NM_NDISC_ROUTER_LIFETIME);
- }
-
- len = nm_ip6_config_get_num_searches(priv->ip_config_6);
- dns_domains = g_array_sized_new(FALSE, TRUE, sizeof(NMNDiscDNSDomain), len);
- g_array_set_size(dns_domains, len);
- for (i = 0; i < len; i++) {
- const char * search = nm_ip6_config_get_search(priv->ip_config_6, i);
- NMNDiscDNSDomain *ndisc_search;
-
- ndisc_search = &g_array_index(dns_domains, NMNDiscDNSDomain, i);
- ndisc_search->domain = (char *) search;
- ndisc_search->expiry_msec =
- _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, NM_NDISC_ROUTER_LIFETIME);
- }
+ if (nm_ndisc_get_node_type(priv->ac6_ndisc) != NM_NDISC_NODE_TYPE_ROUTER)
+ return;
- nm_ndisc_set_config(ndisc, addresses, dns_servers, dns_domains);
+ l3cd = nm_l3cfg_get_combined_l3cd(priv->l3cfg, FALSE);
+ if (l3cd)
+ nm_ndisc_set_config(priv->ac6_ndisc, l3cd);
}
static void
@@ -5272,8 +5630,9 @@ device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink)
}
static gboolean
-device_link_changed(NMDevice *self)
+device_link_changed(gpointer user_data)
{
+ NMDevice * self = user_data;
NMDeviceClass * klass = NM_DEVICE_GET_CLASS(self);
NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
gboolean ip_ifname_changed = FALSE;
@@ -5358,8 +5717,8 @@ device_link_changed(NMDevice *self)
nm_device_emit_recheck_auto_activate(self);
}
- if (priv->ndisc && pllink->inet6_token.id) {
- if (nm_ndisc_set_iid(priv->ndisc, pllink->inet6_token))
+ if (priv->ac6_ndisc && pllink->inet6_token.id) {
+ if (nm_ndisc_set_iid(priv->ac6_ndisc, pllink->inet6_token))
_LOGD(LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
}
@@ -5406,23 +5765,15 @@ device_link_changed(NMDevice *self)
nm_device_set_unmanaged_by_flags(self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason);
}
- set_unmanaged_external_down(self, FALSE);
+ _dev_set_unmanaged_external_down(self, FALSE);
device_recheck_slave_status(self, pllink);
if (priv->up && (!was_up || seen_down)) {
+ priv->linklocal6_dad_counter = 0;
/* the link was down and just came up. That happens for example, while changing MTU.
* We must restore IP configuration. */
- if (NM_IN_SET(priv->ip_state_4, NM_DEVICE_IP_STATE_CONF, NM_DEVICE_IP_STATE_DONE)) {
- if (!ip_config_merge_and_apply(self, AF_INET, TRUE))
- _LOGW(LOGD_IP4, "failed applying IP4 config after link comes up again");
- }
-
- priv->linklocal6_dad_counter = 0;
- if (NM_IN_SET(priv->ip_state_6, NM_DEVICE_IP_STATE_CONF, NM_DEVICE_IP_STATE_DONE)) {
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "failed applying IP6 config after link comes up again");
- }
+ _dev_l3_cfg_commit(self, TRUE);
}
if (update_unmanaged_specs)
@@ -5444,8 +5795,9 @@ device_link_changed(NMDevice *self)
}
static gboolean
-device_ip_link_changed(NMDevice *self)
+device_ip_link_changed(gpointer user_data)
{
+ NMDevice * self = user_data;
NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
const NMPlatformLink *pllink;
const char * ip_iface;
@@ -5508,13 +5860,12 @@ link_changed_cb(NMPlatform * platform,
if (!(info->n_ifi_flags & IFF_UP))
priv->device_link_changed_down = TRUE;
if (!priv->device_link_changed_id) {
- priv->device_link_changed_id = g_idle_add((GSourceFunc) device_link_changed, self);
+ priv->device_link_changed_id = g_idle_add(device_link_changed, self);
_LOGD(LOGD_DEVICE, "queued link change for ifindex %d", ifindex);
}
} else if (ifindex == nm_device_get_ip_ifindex(self)) {
if (!priv->device_ip_link_changed_id) {
- priv->device_ip_link_changed_id =
- g_idle_add((GSourceFunc) device_ip_link_changed, self);
+ priv->device_ip_link_changed_id = g_idle_add(device_ip_link_changed, self);
_LOGD(LOGD_DEVICE, "queued link change for ip-ifindex %d", ifindex);
}
}
@@ -5962,8 +6313,6 @@ realize_start_setup(NMDevice * self,
g_return_if_fail(nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT));
g_return_if_fail(priv->ip_ifindex <= 0);
g_return_if_fail(priv->ip_iface == NULL);
- g_return_if_fail(!priv->queued_ip_config_id_4);
- g_return_if_fail(!priv->queued_ip_config_id_6);
_LOGD(LOGD_DEVICE,
"start setup of %s, kernel ifindex %d",
@@ -6107,9 +6456,6 @@ nm_device_realize_finish(NMDevice *self, const NMPlatformLink *plink)
if (plink)
device_recheck_slave_status(self, plink);
- priv->update_ip_config_completed_v4 = FALSE;
- priv->update_ip_config_completed_v6 = FALSE;
-
priv->real = TRUE;
_notify(self, PROP_REAL);
@@ -6205,9 +6551,6 @@ nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error)
}
}
- nm_clear_g_source(&priv->queued_ip_config_id_4);
- nm_clear_g_source(&priv->queued_ip_config_id_6);
-
g_object_freeze_notify(G_OBJECT(self));
NM_DEVICE_GET_CLASS(self)->unrealize_notify(self);
@@ -6788,6 +7131,9 @@ nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config)
g_return_if_fail(NM_IS_DEVICE(self));
+ _dev_dhcpx_cleanup(self, AF_INET, TRUE, FALSE);
+ _dev_dhcpx_cleanup(self, AF_INET6, TRUE, FALSE);
+
priv = NM_DEVICE_GET_PRIVATE(self);
if (priv->master) {
/* this is called when something externally messes with the slave or during shut-down.
@@ -6799,15 +7145,7 @@ nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config)
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
}
- if (unconfigure_ip_config) {
- nm_device_set_ip_config(self, AF_INET, NULL, FALSE, NULL);
- nm_device_set_ip_config(self, AF_INET6, NULL, FALSE, NULL);
- } else {
- if (priv->dhcp_data_4.client)
- nm_dhcp_client_stop(priv->dhcp_data_4.client, FALSE);
- if (priv->dhcp_data_6.client)
- nm_dhcp_client_stop(priv->dhcp_data_6.client, FALSE);
- }
+ _dev_l3_register_l3cds(self, priv->l3cfg, FALSE, TRUE);
}
static gboolean
@@ -7065,22 +7403,36 @@ nm_device_can_auto_connect(NMDevice *self, NMSettingsConnection *sett_conn, char
static gboolean
device_has_config(NMDevice *self)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ const NMDedupMultiHeadEntry *head_entry;
+ const NMPlatformLink * pllink;
+ NMPLookup lookup;
- /* Check for IP configuration. */
- if (priv->ip_config_4 && nm_ip4_config_get_num_addresses(priv->ip_config_4))
+ pllink = nm_l3cfg_get_pllink(priv->l3cfg, TRUE);
+ if (!pllink)
+ return FALSE;
+
+ if (pllink->master > 0) {
+ /* Master-slave relationship is also a configuration */
return TRUE;
- if (priv->ip_config_6 && nm_ip6_config_get_num_addresses(priv->ip_config_6))
+ }
+
+ head_entry = nm_platform_lookup(
+ nm_device_get_platform(self),
+ nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, pllink->ifindex));
+ if (head_entry)
return TRUE;
- /* The existence of a software device is good enough. */
- if (nm_device_is_software(self) && nm_device_is_real(self))
+ head_entry = nm_platform_lookup(
+ nm_device_get_platform(self),
+ nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP6_ADDRESS, pllink->ifindex));
+ if (head_entry)
return TRUE;
- /* Master-slave relationship is also a configuration */
- if (!c_list_is_empty(&priv->slaves)
- || nm_platform_link_get_master(nm_device_get_platform(self), priv->ifindex) > 0)
+ if (nm_device_is_software(self) && nm_device_is_real(self)) {
+ /* The existence of a software device is good enough. */
return TRUE;
+ }
return FALSE;
}
@@ -7134,7 +7486,8 @@ nm_device_master_update_slave_connection(NMDevice * self,
return FALSE;
}
-static gboolean
+//XXX
+_nm_unused static gboolean
_get_maybe_ipv6_disabled(NMDevice *self)
{
NMPlatform *platform;
@@ -7228,11 +7581,13 @@ nm_device_generate_connection(NMDevice *self,
}
} else {
/* Only regular and master devices get IP configuration; slaves do not */
- s_ip4 = nm_ip4_config_create_setting(priv->ip_config_4);
- nm_connection_add_setting(connection, s_ip4);
+ //XXX s_ip4 = nm_ip4_config_create_setting (priv->ip_config_4);
+ //XXX nm_connection_add_setting (connection, s_ip4);
+ (void) s_ip4;
- s_ip6 = nm_ip6_config_create_setting(priv->ip_config_6, _get_maybe_ipv6_disabled(self));
- nm_connection_add_setting(connection, s_ip6);
+ //XXX s_ip6 = nm_ip6_config_create_setting (priv->ip_config_6, _get_maybe_ipv6_disabled (self));
+ //XXX nm_connection_add_setting (connection, s_ip6);
+ s_ip6 = NULL;
nm_connection_add_setting(connection, nm_setting_proxy_new());
@@ -7685,20 +8040,6 @@ nm_device_emit_recheck_auto_activate(NMDevice *self)
g_signal_emit(self, signals[RECHECK_AUTO_ACTIVATE], 0);
}
-static void
-dnsmasq_state_changed_cb(NMDnsMasqManager *manager, guint32 status, gpointer user_data)
-{
- NMDevice *self = NM_DEVICE(user_data);
-
- switch (status) {
- case NM_DNSMASQ_STATUS_DEAD:
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
- break;
- default:
- break;
- }
-}
-
void
nm_device_auth_request(NMDevice * self,
GDBusMethodInvocation * context,
@@ -8035,6 +8376,7 @@ activate_stage1_device_prepare(NMDevice *self)
priv->v4_route_table_initialized = FALSE;
priv->v6_route_table_initialized = FALSE;
+ priv->l3config_merge_flags_has = FALSE;
_set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_NONE);
_set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_NONE);
@@ -8478,7 +8820,7 @@ activate_stage2_device_config(NMDevice *self)
lldp_setup(self, NM_TERNARY_DEFAULT);
- _commit_mtu(self, NULL);
+ _commit_mtu(self);
nm_device_activate_schedule_stage3_ip_config_start(self);
}
@@ -8513,384 +8855,66 @@ nm_device_ip_method_failed(NMDevice *self, int addr_family, NMDeviceStateReason
/*****************************************************************************/
static void
-acd_data_destroy(gpointer ptr)
-{
- AcdData *data = ptr;
- int i;
-
- for (i = 0; data->configs && data->configs[i]; i++)
- g_object_unref(data->configs[i]);
- g_free(data->configs);
- g_slice_free(AcdData, data);
-}
-
-static void
-ipv4_manual_method_apply(NMDevice *self, NMIP4Config **configs, gboolean success)
-{
- NMConnection *connection;
- const char * method;
-
- connection = nm_device_get_applied_connection(self);
- nm_assert(connection);
- method = nm_utils_get_ip_config_method(connection, AF_INET);
- nm_assert(NM_IN_STRSET(method,
- NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
- NM_SETTING_IP4_CONFIG_METHOD_AUTO));
-
- if (!success) {
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE);
- return;
- }
-
- if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
- nm_device_activate_schedule_ip_config_result(self, AF_INET, NULL);
- else {
- if (NM_DEVICE_GET_PRIVATE(self)->ip_state_4 != NM_DEVICE_IP_STATE_DONE)
- ip_config_merge_and_apply(self, AF_INET, TRUE);
- }
-}
-
-static void
-acd_manager_probe_terminated(NMAcdManager *acd_manager, gpointer user_data)
-{
- AcdData * data = user_data;
- NMDevice * self;
- NMDevicePrivate * priv;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP4Address *address;
- gboolean result, success = TRUE;
- int i;
-
- g_assert(data);
- self = data->device;
- priv = NM_DEVICE_GET_PRIVATE(self);
-
- for (i = 0; data->configs && data->configs[i]; i++) {
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, data->configs[i], &address) {
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
-
- result = nm_acd_manager_check_address(acd_manager, address->address);
- success &= result;
-
- _NMLOG(result ? LOGL_DEBUG : LOGL_WARN,
- LOGD_DEVICE,
- "IPv4 DAD result: address %s is %s",
- _nm_utils_inet4_ntop(address->address, sbuf),
- result ? "unique" : "duplicate");
- }
- }
-
- data->callback(self, data->configs, success);
-
- priv->acd.dad_list = g_slist_remove(priv->acd.dad_list, acd_manager);
- nm_acd_manager_free(acd_manager);
-}
-
-/**
- * ipv4_dad_start:
- * @self: device instance
- * @configs: NULL-terminated array of IPv4 configurations
- * @cb: callback function
- *
- * Start IPv4 DAD on device @self, check addresses in @configs and call @cb
- * when the procedure ends. @cb will be called in any case, even if DAD can't
- * be started. @configs will be unreferenced after @cb has been called.
- */
-static void
-ipv4_dad_start(NMDevice *self, NMIP4Config **configs, AcdCallback cb)
-{
- static const NMAcdCallbacks acd_callbacks = {
- .probe_terminated_callback = acd_manager_probe_terminated,
- .user_data_destroy = acd_data_destroy,
- };
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMAcdManager * acd_manager;
- const NMPlatformIP4Address *address;
- NMDedupMultiIter ipconf_iter;
- AcdData * data;
- guint timeout;
- gboolean addr_found;
- int r;
- const guint8 * hwaddr_arr;
- size_t length;
- guint i;
-
- g_return_if_fail(NM_IS_DEVICE(self));
- g_return_if_fail(configs);
- g_return_if_fail(cb);
-
- for (i = 0, addr_found = FALSE; configs[i]; i++) {
- if (nm_ip4_config_get_num_addresses(configs[i]) > 0) {
- addr_found = TRUE;
- break;
- }
- }
-
- timeout = _prop_get_ipv4_dad_timeout(self);
- hwaddr_arr = nm_platform_link_get_address(nm_device_get_platform(self),
- nm_device_get_ip_ifindex(self),
- &length);
-
- if (!timeout || !hwaddr_arr || !addr_found || length != ETH_ALEN
- || nm_device_sys_iface_state_is_external_or_assume(self)) {
- /* DAD not needed, signal success */
- cb(self, configs, TRUE);
-
- for (i = 0; configs[i]; i++)
- g_object_unref(configs[i]);
- g_free(configs);
-
- return;
- }
-
- data = g_slice_new0(AcdData);
- data->configs = configs;
- data->callback = cb;
- data->device = self;
-
- acd_manager = nm_acd_manager_new(nm_device_get_ip_ifindex(self),
- hwaddr_arr,
- length,
- &acd_callbacks,
- data);
- priv->acd.dad_list = g_slist_append(priv->acd.dad_list, acd_manager);
-
- for (i = 0; configs[i]; i++) {
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, configs[i], &address)
- nm_acd_manager_add_address(acd_manager, address->address);
- }
-
- r = nm_acd_manager_start_probe(acd_manager, timeout);
- if (r < 0) {
- _LOGW(LOGD_DEVICE, "acd probe failed");
-
- /* DAD could not be started, signal success */
- cb(self, configs, TRUE);
-
- priv->acd.dad_list = g_slist_remove(priv->acd.dad_list, acd_manager);
- nm_acd_manager_free(acd_manager);
- }
-}
-
-/*****************************************************************************/
-/* IPv4LL stuff */
-
-static void
-ipv4ll_cleanup(NMDevice *self)
+_dev_ll4_cleanup(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- if (priv->ipv4ll) {
- sd_ipv4ll_set_callback(priv->ipv4ll, NULL, NULL);
- sd_ipv4ll_stop(priv->ipv4ll);
- priv->ipv4ll = sd_ipv4ll_unref(priv->ipv4ll);
- }
-
- nm_clear_g_source(&priv->ipv4ll_timeout);
-}
-
-static NMIP4Config *
-ipv4ll_get_ip4_config(NMDevice *self, guint32 lla)
-{
- NMIP4Config * config = NULL;
- NMPlatformIP4Address address;
- NMPlatformIP4Route route;
+ priv->ll4_ipv4ll_failed = FALSE;
+ priv->ll4_ipv4ll_ready = FALSE;
- config = nm_device_ip4_config_new(self);
- g_assert(config);
-
- memset(&address, 0, sizeof(address));
- nm_platform_ip4_address_set_addr(&address, lla, 16);
- address.addr_source = NM_IP_CONFIG_SOURCE_IP4LL;
- nm_ip4_config_add_address(config, &address);
+ if (nm_clear_pointer(&priv->ll4_ipv4ll, nm_l3_ipv4ll_unref))
+ nm_clear_pointer(&priv->ll4_ipv4ll_registation, nm_l3_ipv4ll_register_remove);
+ else
+ nm_assert(!priv->ll4_ipv4ll_registation);
- /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
- memset(&route, 0, sizeof(route));
- route.network = htonl(0xE0000000L);
- route.plen = 4;
- route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL;
- route.table_coerced = nm_platform_route_table_coerce(nm_device_get_route_table(self, AF_INET));
- route.metric = nm_device_get_route_metric(self, AF_INET);
- nm_ip4_config_add_route(config, &route, NULL);
+ nm_clear_g_source(&priv->ll4_timeout_id);
- return config;
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_LL_4, NULL, FALSE);
}
static void
-nm_device_handle_ipv4ll_event(sd_ipv4ll *ll, int event, void *data)
+_dev_ll4_notify_event(NMDevice *self)
{
- NMDevice * self = data;
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- struct in_addr address;
- NMIP4Config * config;
- int r;
-
- if (priv->act_request.obj == NULL)
- return;
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NML3IPv4LLState ipv4ll_state = NM_L3_IPV4LL_STATE_UNKNOWN;
+ const NML3ConfigData *l3cd;
- nm_assert(nm_streq(nm_device_get_effective_ip_config_method(self, AF_INET),
- NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL));
+ ipv4ll_state =
+ priv->ll4_ipv4ll ? nm_l3_ipv4ll_get_state(priv->ll4_ipv4ll) : NM_L3_IPV4LL_STATE_UNKNOWN;
- switch (event) {
- case SD_IPV4LL_EVENT_BIND:
- r = sd_ipv4ll_get_address(ll, &address);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r);
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED);
- return;
- }
-
- if (!nm_utils_ip4_address_is_link_local(address.s_addr)) {
- _LOGE(LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr);
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
- return;
- }
-
- config = ipv4ll_get_ip4_config(self, address.s_addr);
- if (config == NULL) {
- _LOGE(LOGD_AUTOIP4, "failed to get IPv4LL config");
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
- return;
- }
-
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) {
- nm_clear_g_source(&priv->ipv4ll_timeout);
- nm_device_activate_schedule_ip_config_result(self, AF_INET, NM_IP_CONFIG_CAST(config));
- } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) {
- applied_config_init(&priv->dev_ip_config_4, config);
- if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) {
- _LOGE(LOGD_AUTOIP4, "failed to update IP4 config for autoip change.");
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
- }
- } else
- g_assert_not_reached();
-
- g_object_unref(config);
- break;
- default:
- _LOGW(LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event);
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
+ if (nm_l3_ipv4ll_state_is_good(ipv4ll_state)) {
+ priv->ll4_ipv4ll_failed = FALSE;
+ priv->ll4_ipv4ll_ready = TRUE;
+ l3cd = nm_l3_ipv4ll_get_l3cd(priv->ll4_ipv4ll);
+ nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
+ nm_assert(!nm_l3_ipv4ll_is_timed_out(priv->ll4_ipv4ll));
+ } else {
+ priv->ll4_ipv4ll_failed = (priv->ll4_ipv4ll && nm_l3_ipv4ll_is_timed_out(priv->ll4_ipv4ll));
+ l3cd = NULL;
}
-}
-static gboolean
-ipv4ll_timeout_cb(gpointer user_data)
-{
- NMDevice * self = NM_DEVICE(user_data);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- if (priv->ipv4ll_timeout) {
- _LOGI(LOGD_AUTOIP4, "IPv4LL configuration timed out.");
- priv->ipv4ll_timeout = 0;
- ipv4ll_cleanup(self);
-
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF)
- nm_device_activate_schedule_ip_config_timeout(self, AF_INET);
- }
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_LL_4, l3cd, FALSE);
- return FALSE;
+ _set_ip_state_check(self, AF_INET);
}
static NMActStageReturn
-ipv4ll_start(NMDevice *self)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- const struct ether_addr *addr;
- int ifindex, r;
- size_t addr_len;
-
- ipv4ll_cleanup(self);
-
- r = sd_ipv4ll_new(&priv->ipv4ll);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: new() failed with error %d", r);
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- r = sd_ipv4ll_attach_event(priv->ipv4ll, NULL, 0);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: attach_event() failed with error %d", r);
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- ifindex = nm_device_get_ip_ifindex(self);
- addr = nm_platform_link_get_address(nm_device_get_platform(self), ifindex, &addr_len);
- if (!addr || addr_len != ETH_ALEN) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: can't retrieve hardware address");
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- r = sd_ipv4ll_set_mac(priv->ipv4ll, addr);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: set_mac() failed with error %d", r);
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- r = sd_ipv4ll_set_ifindex(priv->ipv4ll, ifindex);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: set_ifindex() failed with error %d", r);
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- r = sd_ipv4ll_set_callback(priv->ipv4ll, nm_device_handle_ipv4ll_event, self);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: set_callback() failed with error %d", r);
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- r = sd_ipv4ll_start(priv->ipv4ll);
- if (r < 0) {
- _LOGE(LOGD_AUTOIP4, "IPv4LL: start() failed with error %d", r);
- return NM_ACT_STAGE_RETURN_FAILURE;
- }
-
- _LOGI(LOGD_DEVICE | LOGD_AUTOIP4, "IPv4LL: started");
-
- /* Start a timeout to bound the address attempt */
- priv->ipv4ll_timeout = g_timeout_add_seconds(20, ipv4ll_timeout_cb, self);
- return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
-
-static void
-ensure_con_ip_config(NMDevice *self, int addr_family)
+_dev_ll4_start(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMConnection * connection;
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- NMIPConfig * con_ip_config;
+ guint timeout_msec;
- if (priv->con_ip_config_x[IS_IPv4])
- return;
+ _dev_ll4_cleanup(self);
- connection = nm_device_get_applied_connection(self);
- if (!connection)
- return;
+ timeout_msec = _prop_get_ipv4_dad_timeout(self);
+ if (timeout_msec == 0)
+ timeout_msec = NM_ACD_TIMEOUT_RFC5227_MSEC;
- con_ip_config = nm_device_ip_config_new(self, addr_family);
+ _LOGI(LOGD_DEVICE | LOGD_AUTOIP4, "ipv4ll: enabling");
- if (IS_IPv4) {
- nm_ip4_config_merge_setting(NM_IP4_CONFIG(con_ip_config),
- nm_connection_get_setting_ip4_config(connection),
- _prop_get_connection_mdns(self),
- _prop_get_connection_llmnr(self),
- nm_device_get_route_table(self, addr_family),
- nm_device_get_route_metric(self, addr_family));
- } else {
- nm_ip6_config_merge_setting(NM_IP6_CONFIG(con_ip_config),
- nm_connection_get_setting_ip6_config(connection),
- nm_device_get_route_table(self, addr_family),
- nm_device_get_route_metric(self, addr_family));
- }
-
- if (nm_device_sys_iface_state_is_external_or_assume(self)) {
- /* For assumed connections ignore all addresses and routes. */
- nm_ip_config_reset_addresses(con_ip_config);
- nm_ip_config_reset_routes(con_ip_config);
- }
-
- priv->con_ip_config_x[IS_IPv4] = con_ip_config;
+ priv->ll4_ipv4ll = nm_l3cfg_access_ipv4ll(priv->l3cfg);
+ priv->ll4_ipv4ll_registation = nm_l3_ipv4ll_register_new(priv->ll4_ipv4ll, timeout_msec);
+ return NM_ACT_STAGE_RETURN_POSTPONE;
}
/*****************************************************************************/
@@ -8910,487 +8934,221 @@ _device_get_dhcp_anycast_address(NMDevice *self)
return NULL;
}
+/*****************************************************************************/
+
static void
-dhcp4_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release)
+_dev_dhcp4_notify_acd_result(NMDevice *self, gboolean ready)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- priv->dhcp_data_4.was_active = FALSE;
- nm_clear_g_source(&priv->dhcp_data_4.grace_id);
- priv->dhcp_data_4.grace_pending = FALSE;
- nm_clear_g_free(&priv->dhcp4.pac_url);
-
- if (priv->dhcp_data_4.client) {
- /* Stop any ongoing DHCP transaction on this device */
- nm_clear_g_signal_handler(priv->dhcp_data_4.client, &priv->dhcp_data_4.state_sigid);
-
- if (cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED)
- nm_dhcp_client_stop(priv->dhcp_data_4.client, release);
-
- g_clear_object(&priv->dhcp_data_4.client);
+ if (!ready) {
+ nm_dhcp_client_decline(priv->dhcp_data_4.client, "acd failed", NULL);
+ _dev_dhcpx_set_state(self, AF_INET, DHCP_STATE_FAILED);
+ nm_clear_g_source_inst(&priv->dhcp_data_4.grace_source);
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_DHCP_4, NULL, FALSE);
+ } else {
+ nm_dhcp_client_accept(priv->dhcp_data_4.client, NULL);
+ _dev_dhcpx_set_state(self, AF_INET, DHCP_STATE_BOUND);
}
- if (priv->dhcp_data_4.config) {
- nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config);
- _notify(self, PROP_DHCP4_CONFIG);
- }
+ _set_ip_state_check(self, AF_INET);
}
static gboolean
-ip_config_merge_and_apply(NMDevice *self, int addr_family, gboolean commit)
+_dev_dhcpx_set_state(NMDevice *self, int addr_family, DhcpState state)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- gboolean success;
- gs_unref_object NMIPConfig *composite = NULL;
- NMIPConfig * config;
- gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
- NMConnection * connection;
- gboolean ignore_auto_routes = FALSE;
- gboolean ignore_auto_dns = FALSE;
- gboolean ignore_default_routes = FALSE;
- GSList * iter;
- const char * ip6_addr_gen_token = NULL;
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
-
- if (nm_device_sys_iface_state_is_external(self))
- commit = FALSE;
-
- connection = nm_device_get_applied_connection(self);
-
- /* Apply ignore-auto-routes and ignore-auto-dns settings */
- if (connection) {
- NMSettingIPConfig *s_ip;
-
- s_ip = nm_connection_get_setting_ip_config(connection, addr_family);
- if (s_ip) {
- ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes(s_ip);
- ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns(s_ip);
-
- /* if the connection has an explicit gateway, we also ignore
- * the default routes from other sources. */
- ignore_default_routes = nm_setting_ip_config_get_never_default(s_ip)
- || nm_setting_ip_config_get_gateway(s_ip);
-
- if (!IS_IPv4) {
- NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG(s_ip);
-
- if (nm_setting_ip6_config_get_addr_gen_mode(s_ip6)
- == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64)
- ip6_addr_gen_token = nm_setting_ip6_config_get_token(s_ip6);
- }
- }
- }
-
- composite = nm_device_ip_config_new(self, addr_family);
-
- if (!IS_IPv4) {
- nm_ip6_config_set_privacy(NM_IP6_CONFIG(composite),
- priv->ndisc ? priv->ndisc_use_tempaddr
- : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
- }
-
- init_ip_config_dns_priority(self, composite);
-
- if (commit) {
- if (priv->queued_ip_config_id_x[IS_IPv4])
- update_ext_ip_config(self, addr_family, FALSE);
- ensure_con_ip_config(self, addr_family);
- }
-
- if (!IS_IPv4) {
- if (commit && priv->ipv6ll_has) {
- const NMPlatformIP6Address ll_a = {
- .address = priv->ipv6ll_addr,
- .plen = 64,
- .addr_source = NM_IP_CONFIG_SOURCE_IP6LL,
- };
- const NMPlatformIP6Route ll_r = {
- .network.s6_addr16[0] = htons(0xfe80u),
- .plen = 64,
- .metric = nm_device_get_route_metric(self, addr_family),
- .rt_source = NM_IP_CONFIG_SOURCE_IP6LL,
- };
-
- nm_assert(IN6_IS_ADDR_LINKLOCAL(&priv->ipv6ll_addr));
-
- nm_ip6_config_add_address(NM_IP6_CONFIG(composite), &ll_a);
- nm_ip6_config_add_route(NM_IP6_CONFIG(composite), &ll_r, NULL);
- }
- }
-
- if (commit) {
- gboolean v;
-
- v = default_route_metric_penalty_detect(self, addr_family);
- if (IS_IPv4)
- priv->default_route_metric_penalty_ip4_has = v;
- else
- priv->default_route_metric_penalty_ip6_has = v;
- }
-
- /* Merge all the IP configs into the composite config */
-
- if (IS_IPv4) {
- config = applied_config_get_current(&priv->dev_ip_config_4);
- if (config) {
- nm_ip4_config_merge(
- NM_IP4_CONFIG(composite),
- NM_IP4_CONFIG(config),
- (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
- | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
- | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
- default_route_metric_penalty_get(self, addr_family));
- }
- }
-
- if (!IS_IPv4) {
- config = applied_config_get_current(&priv->ac_ip6_config);
- if (config) {
- nm_ip6_config_merge(
- NM_IP6_CONFIG(composite),
- NM_IP6_CONFIG(config),
- (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
- | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
- | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
- default_route_metric_penalty_get(self, addr_family));
- }
- }
-
- if (!IS_IPv4) {
- config = applied_config_get_current(&priv->dhcp6.ip6_config);
- if (config) {
- nm_ip6_config_merge(
- NM_IP6_CONFIG(composite),
- NM_IP6_CONFIG(config),
- (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
- | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
- | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
- default_route_metric_penalty_get(self, addr_family));
- }
- }
-
- for (iter = priv->vpn_configs_x[IS_IPv4]; iter; iter = iter->next)
- nm_ip_config_merge(composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0);
-
- if (priv->ext_ip_config_x[IS_IPv4])
- nm_ip_config_merge(composite,
- priv->ext_ip_config_x[IS_IPv4],
- NM_IP_CONFIG_MERGE_EXTERNAL,
- 0);
-
- /* Merge WWAN config *last* to ensure modem-given settings overwrite
- * any external stuff set by pppd or other scripts.
- */
- config = applied_config_get_current(&priv->dev2_ip_config_x[IS_IPv4]);
- if (config) {
- nm_ip_config_merge(composite,
- config,
- (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
- | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
- | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
- default_route_metric_penalty_get(self, addr_family));
- }
-
- if (!IS_IPv4) {
- if (priv->rt6_temporary_not_available) {
- const NMPObject *o;
- GHashTableIter hiter;
-
- g_hash_table_iter_init(&hiter, priv->rt6_temporary_not_available);
- while (g_hash_table_iter_next(&hiter, (gpointer *) &o, NULL)) {
- nm_ip6_config_add_route(NM_IP6_CONFIG(composite),
- NMP_OBJECT_CAST_IP6_ROUTE(o),
- NULL);
- }
- }
- }
-
- /* Merge user overrides into the composite config. For assumed connections,
- * con_ip_config_x is empty. */
- if (priv->con_ip_config_x[IS_IPv4]) {
- nm_ip_config_merge(composite,
- priv->con_ip_config_x[IS_IPv4],
- NM_IP_CONFIG_MERGE_DEFAULT,
- default_route_metric_penalty_get(self, addr_family));
- }
-
- if (commit) {
- gboolean is_vrf;
-
- is_vrf = priv->master && nm_device_get_device_type(priv->master) == NM_DEVICE_TYPE_VRF;
-
- if (IS_IPv4) {
- nm_ip4_config_add_dependent_routes(NM_IP4_CONFIG(composite),
- nm_device_get_route_table(self, addr_family),
- nm_device_get_route_metric(self, addr_family),
- is_vrf,
- &ip4_dev_route_blacklist);
- } else {
- nm_ip6_config_add_dependent_routes(NM_IP6_CONFIG(composite),
- nm_device_get_route_table(self, addr_family),
- nm_device_get_route_metric(self, addr_family),
- is_vrf);
- }
- }
-
- if (IS_IPv4) {
- if (commit) {
- if (NM_DEVICE_GET_CLASS(self)->ip4_config_pre_commit)
- NM_DEVICE_GET_CLASS(self)->ip4_config_pre_commit(self, NM_IP4_CONFIG(composite));
- }
- }
-
- if (!IS_IPv4) {
- NMUtilsIPv6IfaceId iid;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
- if (commit && priv->ndisc_started && ip6_addr_gen_token
- && nm_utils_ipv6_interface_identifier_get_from_token(&iid, ip6_addr_gen_token)) {
- set_ipv6_token(self, iid, ip6_addr_gen_token);
- }
- }
+ if (priv->dhcp_data_x[IS_IPv4].state == state)
+ return FALSE;
- success =
- nm_device_set_ip_config(self, addr_family, composite, commit, ip4_dev_route_blacklist);
- if (commit) {
- if (IS_IPv4)
- priv->v4_commit_first_time = FALSE;
- else
- priv->v6_commit_first_time = FALSE;
- }
+ _LOGD(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c: set state '%s' (was '%s')",
+ nm_utils_addr_family_to_char(addr_family),
+ _dhcp_state_to_string(state),
+ _dhcp_state_to_string(priv->dhcp_data_x[IS_IPv4].state));
- return success;
+ priv->dhcp_data_x[IS_IPv4].state = state;
+ return TRUE;
}
-static gboolean
-dhcp4_lease_change(NMDevice *self, NMIP4Config *config, gboolean bound)
+static void
+_dev_dhcpx_cleanup(NMDevice *self, int addr_family, gboolean reset_dhcp_config, gboolean release)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- gs_free_error GError *error = NULL;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+
+ if (!IS_IPv4)
+ priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE;
- g_return_val_if_fail(config, FALSE);
+ nm_clear_g_source_inst(&priv->dhcp_data_x[IS_IPv4].grace_source);
- applied_config_init(&priv->dev_ip_config_4, config);
+ _dev_dhcpx_set_state(self, addr_family, DHCP_STATE_NONE);
- if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) {
- _LOGW(LOGD_DHCP4, "failed to update IPv4 config for DHCP change.");
- return FALSE;
- }
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4), NULL, FALSE);
- /* TODO: we should perform DAD again whenever we obtain a
- * new lease after an expiry. But what should we do if
- * a duplicate address is detected? Fail the connection;
- * restart DHCP; continue without an address? */
- if (bound && !nm_dhcp_client_accept(priv->dhcp_data_4.client, &error)) {
- _LOGW(LOGD_DHCP4, "error accepting lease: %s", error->message);
- return FALSE;
+ if (priv->dhcp_data_x[IS_IPv4].client) {
+ /* Stop any ongoing DHCP transaction on this device */
+ nm_clear_g_signal_handler(priv->dhcp_data_x[IS_IPv4].client,
+ &priv->dhcp_data_x[IS_IPv4].state_sigid);
+ if (!IS_IPv4)
+ nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp6.prefix_sigid);
+ nm_dhcp_client_stop(priv->dhcp_data_x[IS_IPv4].client, release);
+ g_clear_object(&priv->dhcp_data_x[IS_IPv4].client);
}
- nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP4_CHANGE, self, NULL, NULL, NULL, NULL);
-
- return TRUE;
+ if (reset_dhcp_config) {
+ if (nm_dbus_object_clear_and_unexport(&priv->dhcp_data_x[IS_IPv4].config))
+ _notify(self, PROP_DHCPX_CONFIG(IS_IPv4));
+ }
}
static gboolean
-dhcp_grace_period_expired(NMDevice *self, int addr_family)
+_dev_dhcpx_grace_period_expired(NMDevice *self, int addr_family)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
const int IS_IPv4 = NM_IS_IPv4(addr_family);
- priv->dhcp_data_x[IS_IPv4].grace_id = 0;
- priv->dhcp_data_x[IS_IPv4].grace_pending = FALSE;
+ nm_clear_g_source_inst(&priv->dhcp_data_x[IS_IPv4].grace_source);
- _LOGI(LOGD_DHCPX(IS_IPv4),
- "DHCPv%c: grace period expired",
+ _LOGD(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c: grace period expired",
nm_utils_addr_family_to_char(addr_family));
- nm_device_ip_method_failed(self, addr_family, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
- /* If the device didn't fail, the DHCP client will continue */
-
- return G_SOURCE_REMOVE;
+ _set_ip_state_check(self, addr_family);
+ return G_SOURCE_CONTINUE;
}
static gboolean
-dhcp_grace_period_expired_4(gpointer user_data)
+_dev_dhcpx_grace_period_expired_4(gpointer user_data)
{
- return dhcp_grace_period_expired(user_data, AF_INET);
+ return _dev_dhcpx_grace_period_expired(user_data, AF_INET);
}
static gboolean
-dhcp_grace_period_expired_6(gpointer user_data)
+_dev_dhcpx_grace_period_expired_6(gpointer user_data)
{
- return dhcp_grace_period_expired(user_data, AF_INET6);
+ return _dev_dhcpx_grace_period_expired(user_data, AF_INET6);
}
static gboolean
-dhcp_grace_period_start(NMDevice *self, int addr_family)
+_dev_dhcpx_grace_period_start(NMDevice *self,
+ int addr_family,
+ guint32 timeout_sec,
+ gboolean force_restart)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
const int IS_IPv4 = NM_IS_IPv4(addr_family);
- guint32 timeout;
/* In any other case (expired lease, assumed connection, etc.),
* wait for some time before failing the IP method.
*/
- if (priv->dhcp_data_x[IS_IPv4].grace_pending) {
+ if (!force_restart && priv->dhcp_data_x[IS_IPv4].grace_source) {
/* already pending. */
return FALSE;
}
/* Start a grace period equal to the DHCP timeout multiplied
* by a constant factor. */
- timeout = _prop_get_ipvx_dhcp_timeout(self, addr_family);
- if (timeout == NM_DHCP_TIMEOUT_INFINITY)
- _LOGI(LOGD_DHCPX(IS_IPv4),
- "DHCPv%c: trying to acquire a new lease",
- nm_utils_addr_family_to_char(addr_family));
- else {
- timeout = dhcp_grace_period_from_timeout(timeout);
- _LOGI(LOGD_DHCPX(IS_IPv4),
- "DHCPv%c: trying to acquire a new lease within %u seconds",
- nm_utils_addr_family_to_char(addr_family),
- timeout);
- nm_assert(!priv->dhcp_data_x[IS_IPv4].grace_id);
- priv->dhcp_data_x[IS_IPv4].grace_id = g_timeout_add_seconds(
- timeout,
- IS_IPv4 ? dhcp_grace_period_expired_4 : dhcp_grace_period_expired_6,
- self);
- }
-
- priv->dhcp_data_x[IS_IPv4].grace_pending = TRUE;
-
- return TRUE;
-}
-static void
-dhcp4_fail(NMDevice *self, NMDhcpState dhcp_state)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- _LOGD(LOGD_DHCP4,
- "DHCPv4 failed (ip_state %s, was_active %d)",
- nm_device_ip_state_to_str(priv->ip_state_4),
- priv->dhcp_data_4.was_active);
+ nm_clear_g_source_inst(&priv->dhcp_data_x[IS_IPv4].grace_source);
- /* The client is always left running after a failure. */
+ if (timeout_sec == 0)
+ timeout_sec = _prop_get_ipvx_dhcp_timeout(self, addr_family);
- /* Nothing to do if we failed before... */
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL)
- goto clear_config;
-
- /* ... and also if there are static addresses configured
- * on the interface.
- */
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && priv->con_ip_config_4
- && nm_ip4_config_get_num_addresses(priv->con_ip_config_4) > 0)
- goto clear_config;
-
- /* Fail the method when one of the following is true:
- * 1) the DHCP client terminated: it does not make sense to start a grace
- * period without a client running;
- * 2) we failed to get an initial lease AND the client was
- * not active before.
- */
- if (dhcp_state == NM_DHCP_STATE_TERMINATED
- || (!priv->dhcp_data_4.was_active && priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF)) {
- nm_device_activate_schedule_ip_config_timeout(self, AF_INET);
- return;
- }
+ if (timeout_sec == NM_DHCP_TIMEOUT_INFINITY) {
+ _LOGD(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c: trying to acquire a new lease",
+ nm_utils_addr_family_to_char(addr_family));
+ priv->dhcp_data_x[IS_IPv4].grace_source = g_source_ref(nm_g_source_sentinel_get(0));
+ } else {
+ guint timeout_msec;
- if (dhcp_grace_period_start(self, AF_INET))
- goto clear_config;
+ if (timeout_sec < G_MAXUINT / 1000u)
+ timeout_msec = timeout_sec * 1000u;
+ else
+ timeout_msec = G_MAXUINT;
- return;
+ _LOGD(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c: trying to acquire a new lease within %u seconds",
+ nm_utils_addr_family_to_char(addr_family),
+ timeout_sec);
-clear_config:
- /* The previous configuration is no longer valid */
- if (priv->dhcp_data_4.config) {
- nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config);
- priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET);
- _notify(self, PROP_DHCP4_CONFIG);
+ priv->dhcp_data_x[IS_IPv4].grace_source =
+ nm_g_source_attach(nm_g_timeout_source_new(timeout_msec,
+ G_PRIORITY_DEFAULT,
+ IS_IPv4 ? _dev_dhcpx_grace_period_expired_4
+ : _dev_dhcpx_grace_period_expired_6,
+ self,
+ NULL),
+ NULL);
}
-}
-static void
-dhcp4_dad_cb(NMDevice *self, NMIP4Config **configs, gboolean success)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- if (success) {
- nm_device_activate_schedule_ip_config_result(self, AF_INET, NM_IP_CONFIG_CAST(configs[1]));
- } else {
- nm_dhcp_client_decline(priv->dhcp_data_4.client, "Address conflict detected", NULL);
- nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE);
- }
+ return TRUE;
}
static void
-dhcp4_state_changed(NMDhcpClient *client,
- NMDhcpState state,
- NMIP4Config * ip4_config,
- GHashTable * options,
- gpointer user_data)
+_dev_dhcpx_state_changed(NMDevice * self,
+ int addr_family,
+ NMDhcpState state,
+ const NML3ConfigData *l3cd)
{
- NMDevice * self = NM_DEVICE(user_data);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMIP4Config * manual, **configs;
- NMConnection * connection;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_merged = NULL;
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
- g_return_if_fail(nm_dhcp_client_get_addr_family(client) == AF_INET);
- g_return_if_fail(!ip4_config || NM_IS_IP4_CONFIG(ip4_config));
+ nm_assert(NM_IN_SET(state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED) == (!!l3cd));
- _LOGD(LOGD_DHCP4, "new DHCPv4 client state %d", state);
+ _LOGD(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c: new DHCP client state %s",
+ nm_utils_addr_family_to_char(addr_family),
+ nm_dhcp_state_to_string(state));
switch (state) {
case NM_DHCP_STATE_BOUND:
case NM_DHCP_STATE_EXTENDED:
- if (!ip4_config) {
- _LOGW(LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event.");
- dhcp4_fail(self, state);
- break;
- }
- nm_clear_g_source(&priv->dhcp_data_4.grace_id);
- priv->dhcp_data_4.grace_pending = FALSE;
+ nm_assert(l3cd);
- /* After some failures, we have been able to renew the lease:
- * update the ip state
+ /* If the server sends multiple IPv6 addresses, we receive a state
+ * changed event for each of them. Use the event ID to merge IPv6
+ * addresses from the same transaction into a single configuration.
*/
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL)
- _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_CONF);
+ if (!IS_IPv4) {
+ if (nm_dhcp_utils_merge_new_dhcp6_lease(priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_6].d,
+ l3cd,
+ &l3cd_merged)) {
+ _LOGD(LOGD_DHCP6, "merged DHCPv6 lease with previous lease");
+ l3cd = l3cd_merged;
+ }
+ }
- g_free(priv->dhcp4.pac_url);
- priv->dhcp4.pac_url = g_strdup(g_hash_table_lookup(options, "wpad"));
- nm_device_set_proxy_config(self, priv->dhcp4.pac_url);
+ nm_clear_g_source_inst(&priv->dhcp_data_x[IS_IPv4].grace_source);
- nm_dhcp_config_set_options(priv->dhcp_data_4.config, options);
- _notify(self, PROP_DHCP4_CONFIG);
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4), l3cd, FALSE);
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) {
- connection = nm_device_get_applied_connection(self);
- g_assert(connection);
+ nm_dhcp_config_set_lease(priv->dhcp_data_x[IS_IPv4].config, l3cd);
- manual = nm_device_ip4_config_new(self);
- nm_ip4_config_merge_setting(manual,
- nm_connection_get_setting_ip4_config(connection),
- NM_SETTING_CONNECTION_MDNS_DEFAULT,
- NM_SETTING_CONNECTION_LLMNR_DEFAULT,
- nm_device_get_route_table(self, AF_INET),
- nm_device_get_route_metric(self, AF_INET));
+ _set_ip_state_check(self, addr_family);
- configs = g_new0(NMIP4Config *, 3);
- configs[0] = manual;
- configs[1] = g_object_ref(ip4_config);
+ _dev_l3_cfg_commit(self, TRUE);
- ipv4_dad_start(self, configs, dhcp4_dad_cb);
- } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) {
- if (dhcp4_lease_change(self, ip4_config, state == NM_DHCP_STATE_BOUND))
- nm_device_update_metered(self);
- else
- dhcp4_fail(self, state);
+ _dev_l3_notify_change(self, addr_family);
+
+ if (!IS_IPv4) {
+ /* FIXME(l3cfg): check where and how to dispatch DHCP change notifications. */
+ nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP6_CHANGE,
+ self,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
+
break;
case NM_DHCP_STATE_TIMEOUT:
- dhcp4_fail(self, state);
- break;
+ goto out_fail;
case NM_DHCP_STATE_EXPIRE:
/* Ignore expiry before we even have a lease (NAK, old lease, etc) */
if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF)
@@ -9399,50 +9157,109 @@ dhcp4_state_changed(NMDhcpClient *client,
case NM_DHCP_STATE_DONE:
case NM_DHCP_STATE_FAIL:
case NM_DHCP_STATE_TERMINATED:
- dhcp4_fail(self, state);
- break;
+ goto out_fail;
default:
break;
}
+
+out_fail:
+ //XXX _LOGD(LOGD_DHCPX(IS_IPv4),
+ //XXX "dhcp%c failed (ip_state %s, was_active %d)",
+ //XXX nm_utils_addr_family_to_char(addr_family),
+ //XXX nm_device_ip_state_to_str(priv->ip_state_x[IS_IPv4]),
+ //XXX (int) priv->dhcp_data_x[IS_IPv4].was_active);
+
+ _dev_dhcpx_grace_period_start(self, addr_family, 0, FALSE);
+ //XXX priv->dhcp_data_x[IS_IPv4].is_bad = TRUE;
+ _set_ip_state_check(self, addr_family);
}
-static NMActStageReturn
-dhcp4_start(NMDevice *self)
+/*****************************************************************************/
+
+static void
+_dev_dhcpx_state_changed_4(NMDhcpClient * client,
+ guint state,
+ const NML3ConfigData *l3cd,
+ gpointer user_data)
{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMSettingIPConfig *s_ip4;
- gs_unref_bytes GBytes *vendor_class_identifier = NULL;
- gs_unref_bytes GBytes *hwaddr = NULL;
- gs_unref_bytes GBytes *bcast_hwaddr = NULL;
- gs_unref_bytes GBytes *client_id = NULL;
- gs_free char * mud_url_free = NULL;
- NMConnection * connection;
- NMSettingConnection * s_con;
- GError * error = NULL;
- const NMPlatformLink * pllink;
- const char *const * reject_servers;
- gboolean request_broadcast;
- const char * str;
+ _dev_dhcpx_state_changed(user_data, AF_INET, state, l3cd);
+}
+
+static void
+_dev_dhcpx_state_changed_6(NMDhcpClient * client,
+ guint state,
+ const NML3ConfigData *l3cd,
+ gpointer user_data)
+{
+ _dev_dhcpx_state_changed(user_data, AF_INET6, state, l3cd);
+}
+
+static void
+_dev_dhcp6_prefix_delegated(NMDhcpClient *client, NMPlatformIP6Address *prefix, gpointer user_data)
+{
+ NMDevice *self = NM_DEVICE(user_data);
+
+ /* Just re-emit. The device just contributes the prefix to the
+ * pool in NMPolicy, which decides about subnet allocation
+ * on the shared devices. */
+ g_signal_emit(self, signals[IP6_PREFIX_DELEGATED], 0, prefix);
+}
+
+static gboolean
+_dev_dhcpx_start(NMDevice *self, int addr_family)
+{
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NMConnection * connection;
+ NMSettingConnection *s_con;
+ NMSettingIPConfig * s_ip;
+ struct in6_addr ll_addr = IN6ADDR_ANY_INIT;
+ gs_unref_bytes GBytes *hwaddr = NULL;
+ gboolean enforce_duid = FALSE;
+ gs_free char * mud_url_free = NULL;
+ gs_free_error GError *error = NULL;
+ const NMPlatformLink *pllink;
+ guint32 timeout_sec;
+ int ifindex;
+ const char * str;
+ gboolean request_broadcast;
+
+ nm_assert(priv->dhcp_data_x[IS_IPv4].client == NULL);
+
+ if (nm_device_sys_iface_state_is_external(self))
+ g_return_val_if_reached(TRUE);
connection = nm_device_get_applied_connection(self);
g_return_val_if_fail(connection, FALSE);
- s_ip4 = nm_connection_get_setting_ip4_config(connection);
-
s_con = nm_connection_get_setting_connection(connection);
+ s_ip = nm_connection_get_setting_ip_config(connection, addr_family);
nm_assert(s_con);
+ nm_assert(s_ip);
- /* Clear old exported DHCP options */
- nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config);
- priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET);
-
- request_broadcast = FALSE;
+ ifindex = 0;
- pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self));
+ pllink = nm_l3cfg_get_pllink(priv->l3cfg, TRUE);
if (pllink) {
- hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address);
- bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast);
+ ifindex = pllink->ifindex;
+ nm_assert(ifindex > 0);
+ nm_assert(ifindex == nm_device_get_ip_ifindex(self));
+ }
+
+ if (ifindex <= 0)
+ g_return_val_if_reached(TRUE);
+ hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address);
+
+ if (!IS_IPv4) {
+ if (!hwaddr) {
+ _LOGD(LOGD_DHCP6, "dhcp6: cannot start DHCP with no suitable interface");
+ return FALSE;
+ }
+ }
+
+ request_broadcast = FALSE;
+ if (pllink) {
str = nmp_object_link_udev_device_get_property_value(NMP_OBJECT_UP_CAST(pllink),
"ID_NET_DHCP_BROADCAST");
if (str && _nm_utils_ascii_str_to_bool(str, FALSE)) {
@@ -9454,103 +9271,154 @@ dhcp4_start(NMDevice *self)
}
}
- client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr);
- vendor_class_identifier =
- _prop_get_ipv4_dhcp_vendor_class_identifier(self, NM_SETTING_IP4_CONFIG(s_ip4));
- reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip4, NULL);
-
- g_warn_if_fail(priv->dhcp_data_4.client == NULL);
- priv->dhcp_data_4.client = nm_dhcp_manager_start_ip4(
- nm_dhcp_manager_get(),
- nm_netns_get_multi_idx(nm_device_get_netns(self)),
- nm_device_get_ip_iface(self),
- nm_device_get_ip_ifindex(self),
- hwaddr,
- bcast_hwaddr,
- nm_connection_get_uuid(connection),
- nm_device_get_route_table(self, AF_INET),
- nm_device_get_route_metric(self, AF_INET),
- request_broadcast ? NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST : NM_DHCP_CLIENT_FLAGS_NONE,
- nm_setting_ip_config_get_dhcp_send_hostname(s_ip4),
- nm_setting_ip_config_get_dhcp_hostname(s_ip4),
- nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)),
- _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET),
- _prop_get_connection_mud_url(self, s_con, &mud_url_free),
- client_id,
- _prop_get_ipvx_dhcp_timeout(self, AF_INET),
- _device_get_dhcp_anycast_address(self),
- NULL,
- vendor_class_identifier,
- reject_servers,
- &error);
- if (!priv->dhcp_data_4.client) {
- _LOGW(LOGD_DHCP4, "failure to start DHCP: %s", error->message);
- g_clear_error(&error);
- return NM_ACT_STAGE_RETURN_FAILURE;
+ timeout_sec = _prop_get_ipvx_dhcp_timeout(self, addr_family);
+
+ _dev_dhcpx_grace_period_start(self, addr_family, timeout_sec, TRUE);
+
+ if (!IS_IPv4) {
+ if (!_dev_ll6_start(self, &ll_addr)) {
+ /* wait for the LL address to show up */
+ return TRUE;
+ }
}
- priv->dhcp_data_4.state_sigid = g_signal_connect(priv->dhcp_data_4.client,
- NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
- G_CALLBACK(dhcp4_state_changed),
- self);
+ if (IS_IPv4) {
+ gs_unref_bytes GBytes *bcast_hwaddr = NULL;
+ gs_unref_bytes GBytes *client_id = NULL;
+ gs_unref_bytes GBytes *vendor_class_identifier = NULL;
+ const char *const * reject_servers;
- if (nm_device_sys_iface_state_is_external_or_assume(self))
- priv->dhcp_data_4.was_active = TRUE;
+ client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr);
+ vendor_class_identifier =
+ _prop_get_ipv4_dhcp_vendor_class_identifier(self, NM_SETTING_IP4_CONFIG(s_ip));
+ reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip, NULL);
- /* DHCP devices will be notified by the DHCP manager when stuff happens */
- return NM_ACT_STAGE_RETURN_POSTPONE;
+ bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast);
+
+ priv->dhcp_data_4.client = nm_dhcp_manager_start_ip4(
+ nm_dhcp_manager_get(),
+ nm_netns_get_multi_idx(nm_device_get_netns(self)),
+ nm_device_get_ip_iface(self),
+ nm_device_get_ip_ifindex(self),
+ hwaddr,
+ bcast_hwaddr,
+ nm_connection_get_uuid(connection),
+ request_broadcast ? NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST : NM_DHCP_CLIENT_FLAGS_NONE,
+ nm_setting_ip_config_get_dhcp_send_hostname(s_ip),
+ nm_setting_ip_config_get_dhcp_hostname(s_ip),
+ nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip)),
+ _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET),
+ _prop_get_connection_mud_url(self, s_con, &mud_url_free),
+ client_id,
+ timeout_sec,
+ _device_get_dhcp_anycast_address(self),
+ NULL,
+ vendor_class_identifier,
+ reject_servers,
+ &error);
+ } else {
+ gs_unref_bytes GBytes *duid = NULL;
+ gboolean iaid_explicit;
+ guint32 iaid;
+
+ iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET6, connection, FALSE, &iaid_explicit);
+ duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, &enforce_duid);
+
+ priv->dhcp_data_6.client = nm_dhcp_manager_start_ip6(
+ nm_dhcp_manager_get(),
+ nm_device_get_multi_index(self),
+ nm_device_get_ip_iface(self),
+ ifindex,
+ &ll_addr,
+ nm_connection_get_uuid(connection),
+ (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY
+ : NM_DHCP_CLIENT_FLAGS_NONE,
+ nm_setting_ip_config_get_dhcp_send_hostname(s_ip),
+ nm_setting_ip_config_get_dhcp_hostname(s_ip),
+ _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET6),
+ _prop_get_connection_mud_url(self, s_con, &mud_url_free),
+ duid,
+ enforce_duid,
+ iaid,
+ iaid_explicit,
+ _prop_get_ipvx_dhcp_timeout(self, AF_INET6),
+ _device_get_dhcp_anycast_address(self),
+ nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip)),
+ priv->dhcp6.needed_prefixes,
+ &error);
+ }
+
+ if (nm_device_sys_iface_state_is_external_or_assume(self)) {
+ //XXX priv->dhcp_data_x[IS_IPv4].was_active = TRUE;
+ }
+
+ if (!priv->dhcp_data_x[IS_IPv4].client) {
+ _LOGW(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c: failure to start DHCP client: %s",
+ nm_utils_addr_family_to_char(addr_family),
+ error->message);
+ _dev_dhcpx_cleanup(self, addr_family, TRUE, TRUE);
+ return FALSE;
+ }
+
+ priv->dhcp_data_x[IS_IPv4].state_sigid = g_signal_connect(
+ priv->dhcp_data_x[IS_IPv4].client,
+ NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
+ IS_IPv4 ? G_CALLBACK(_dev_dhcpx_state_changed_4) : G_CALLBACK(_dev_dhcpx_state_changed_6),
+ self);
+ if (!IS_IPv4) {
+ priv->dhcp6.prefix_sigid = g_signal_connect(priv->dhcp_data_6.client,
+ NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED,
+ G_CALLBACK(_dev_dhcp6_prefix_delegated),
+ self);
+ }
+
+ if (!priv->dhcp_data_x[IS_IPv4].config) {
+ priv->dhcp_data_x[IS_IPv4].config = nm_dhcp_config_new(addr_family);
+ _notify(self, PROP_DHCPX_CONFIG(IS_IPv4));
+ } else
+ nm_dhcp_config_set_lease(priv->dhcp_data_x[IS_IPv4].config, NULL);
+
+ return TRUE;
}
-gboolean
-nm_device_dhcp4_renew(NMDevice *self, gboolean release)
+static void
+_dev_dhcp6_set_dhcp_level(NMDevice *self, NMNDiscDHCPLevel dhcp_level)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- g_return_val_if_fail(priv->dhcp_data_4.client != NULL, FALSE);
+ if (priv->dhcp6.mode == dhcp_level)
+ return;
- _LOGI(LOGD_DHCP4, "DHCPv4 lease renewal requested");
+ _LOGD(LOGD_DEVICE | LOGD_DHCP6, "reset DHCPv6 level to %d", (int) dhcp_level);
- /* Terminate old DHCP instance and release the old lease */
- dhcp4_cleanup(self, CLEANUP_TYPE_DECONFIGURE, release);
+ _dev_dhcpx_cleanup(self, AF_INET6, TRUE, TRUE);
- /* Start DHCP again on the interface */
- return dhcp4_start(self) != NM_ACT_STAGE_RETURN_FAILURE;
+ priv->dhcp6.mode = dhcp_level;
+ if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_NONE)
+ return;
+
+ _dev_dhcpx_start(self, AF_INET6);
}
/*****************************************************************************/
-static NMIP4Config *
-shared4_new_config(NMDevice *self, NMConnection *connection)
+gboolean
+nm_device_dhcp_renew(NMDevice *self, int addr_family, gboolean release)
{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMIP4Config * config;
- NMSettingIPConfig * s_ip4;
- NMPlatformIP4Address address = {
- .addr_source = NM_IP_CONFIG_SOURCE_SHARED,
- };
-
- g_return_val_if_fail(self, NULL);
- g_return_val_if_fail(connection, NULL);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
- s_ip4 = nm_connection_get_setting_ip4_config(connection);
- if (s_ip4 && nm_setting_ip_config_get_num_addresses(s_ip4) > 0) {
- /* Use the first user-supplied address */
- NMIPAddress *user = nm_setting_ip_config_get_address(s_ip4, 0);
- in_addr_t a;
+ if (!priv->dhcp_data_x[IS_IPv4].client)
+ g_return_val_if_reached(FALSE);
- nm_ip_address_get_address_binary(user, &a);
- nm_platform_ip4_address_set_addr(&address, a, nm_ip_address_get_prefix(user));
- nm_clear_pointer(&priv->shared_ip_handle, nm_netns_shared_ip_release);
- } else {
- if (!priv->shared_ip_handle)
- priv->shared_ip_handle = nm_netns_shared_ip_reserve(nm_device_get_netns(self));
- nm_platform_ip4_address_set_addr(&address, priv->shared_ip_handle->addr, 24);
- }
+ _LOGI(LOGD_DHCPX(IS_IPv4),
+ "dhcp%c lease renewal requested",
+ nm_utils_addr_family_to_char(addr_family));
- config = nm_device_ip4_config_new(self);
- nm_ip4_config_add_address(config, &address);
+ _dev_dhcpx_cleanup(self, addr_family, FALSE, release);
- return config;
+ return _dev_dhcpx_start(self, addr_family);
}
/*****************************************************************************/
@@ -9648,367 +9516,6 @@ have_any_ready_slaves(NMDevice *self)
}
/*****************************************************************************/
-/* DHCPv6 stuff */
-
-static void
-dhcp6_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- priv->dhcp_data_6.was_active = FALSE;
- priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE;
- applied_config_clear(&priv->dhcp6.ip6_config);
- nm_clear_g_free(&priv->dhcp6.event_id);
- nm_clear_g_source(&priv->dhcp_data_6.grace_id);
- priv->dhcp_data_6.grace_pending = FALSE;
-
- if (priv->dhcp_data_6.client) {
- nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp_data_6.state_sigid);
- nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp6.prefix_sigid);
-
- if (cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED)
- nm_dhcp_client_stop(priv->dhcp_data_6.client, release);
-
- g_clear_object(&priv->dhcp_data_6.client);
- }
-
- if (priv->dhcp_data_6.config) {
- nm_dbus_object_clear_and_unexport(&priv->dhcp_data_6.config);
- _notify(self, PROP_DHCP6_CONFIG);
- }
-}
-
-static gboolean
-dhcp6_lease_change(NMDevice *self)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMSettingsConnection *settings_connection;
-
- if (!applied_config_get_current(&priv->dhcp6.ip6_config)) {
- _LOGW(LOGD_DHCP6, "failed to get DHCPv6 config for rebind");
- return FALSE;
- }
-
- g_assert(priv->dhcp_data_6.client); /* sanity check */
-
- settings_connection = nm_device_get_settings_connection(self);
- g_assert(settings_connection);
-
- /* Apply the updated config */
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) {
- _LOGW(LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event");
- return FALSE;
- }
-
- nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP6_CHANGE, self, NULL, NULL, NULL, NULL);
-
- return TRUE;
-}
-
-static void
-dhcp6_fail(NMDevice *self, NMDhcpState dhcp_state)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- gboolean is_dhcp_managed;
-
- _LOGD(LOGD_DHCP6,
- "DHCPv6 failed (ip_state %s, was_active %d)",
- nm_device_ip_state_to_str(priv->ip_state_6),
- priv->dhcp_data_6.was_active);
-
- /* The client is always left running after a failure. */
-
- /* Nothing to do if we failed before... */
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL)
- goto clear_config;
-
- is_dhcp_managed = (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED);
-
- if (is_dhcp_managed) {
- /* ... and also if there are static addresses configured
- * on the interface.
- */
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE && priv->con_ip_config_6
- && nm_ip6_config_get_num_addresses(priv->con_ip_config_6))
- goto clear_config;
-
- /* Fail the method when one of the following is true:
- * 1) the DHCP client terminated: it does not make sense to start a grace
- * period without a client running;
- * 2) we failed to get an initial lease AND the client was
- * not active before.
- */
- if (dhcp_state == NM_DHCP_STATE_TERMINATED
- || (!priv->dhcp_data_6.was_active && priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF)) {
- nm_device_activate_schedule_ip_config_timeout(self, AF_INET6);
- return;
- }
-
- if (dhcp_grace_period_start(self, AF_INET6))
- goto clear_config;
- } else {
- /* not a hard failure; just live with the RA info */
- dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, FALSE);
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF)
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
- }
- return;
-
-clear_config:
- /* The previous configuration is no longer valid */
- if (priv->dhcp_data_6.config) {
- nm_dbus_object_clear_and_unexport(&priv->dhcp_data_6.config);
- priv->dhcp_data_6.config = nm_dhcp_config_new(AF_INET6);
- _notify(self, PROP_DHCP6_CONFIG);
- }
-}
-
-static void
-dhcp6_state_changed(NMDhcpClient *client,
- NMDhcpState state,
- NMIP6Config * ip6_config,
- GHashTable * options,
- gpointer user_data)
-{
- NMDevice * self = NM_DEVICE(user_data);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- gs_free char * event_id = NULL;
-
- g_return_if_fail(nm_dhcp_client_get_addr_family(client) == AF_INET6);
- g_return_if_fail(!ip6_config || NM_IS_IP6_CONFIG(ip6_config));
-
- _LOGD(LOGD_DHCP6, "new DHCPv6 client state %d", state);
-
- switch (state) {
- case NM_DHCP_STATE_BOUND:
- case NM_DHCP_STATE_EXTENDED:
- nm_clear_g_source(&priv->dhcp_data_6.grace_id);
- priv->dhcp_data_6.grace_pending = FALSE;
- /* If the server sends multiple IPv6 addresses, we receive a state
- * changed event for each of them. Use the event ID to merge IPv6
- * addresses from the same transaction into a single configuration.
- */
-
- event_id = nm_dhcp_utils_get_dhcp6_event_id(options);
-
- if (ip6_config && event_id && priv->dhcp6.event_id
- && nm_streq(event_id, priv->dhcp6.event_id)) {
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *a;
-
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6_config, &a)
- applied_config_add_address(&priv->dhcp6.ip6_config, NM_PLATFORM_IP_ADDRESS_CAST(a));
- } else {
- nm_clear_g_free(&priv->dhcp6.event_id);
- if (ip6_config) {
- applied_config_init(&priv->dhcp6.ip6_config, ip6_config);
- priv->dhcp6.event_id = g_strdup(event_id);
- nm_dhcp_config_set_options(priv->dhcp_data_6.config, options);
- _notify(self, PROP_DHCP6_CONFIG);
- } else
- applied_config_clear(&priv->dhcp6.ip6_config);
- }
-
- /* After long time we have been able to renew the lease:
- * update the ip state
- */
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL)
- _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_CONF);
-
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) {
- if (!applied_config_get_current(&priv->dhcp6.ip6_config)) {
- nm_device_ip_method_failed(self, AF_INET6, NM_DEVICE_STATE_REASON_DHCP_FAILED);
- break;
- }
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
- } else if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE)
- if (!dhcp6_lease_change(self))
- dhcp6_fail(self, state);
- break;
- case NM_DHCP_STATE_TIMEOUT:
- if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED)
- dhcp6_fail(self, state);
- else {
- /* not a hard failure; just live with the RA info */
- dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, FALSE);
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF)
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
- }
- break;
- case NM_DHCP_STATE_EXPIRE:
- /* Ignore expiry before we even have a lease (NAK, old lease, etc) */
- if (priv->ip_state_6 != NM_DEVICE_IP_STATE_CONF)
- dhcp6_fail(self, state);
- break;
- case NM_DHCP_STATE_TERMINATED:
- /* In IPv6 info-only mode, the client doesn't handle leases so it
- * may exit right after getting a response from the server. That's
- * normal. In that case we just ignore the exit.
- */
- if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF)
- break;
- /* fall-through */
- case NM_DHCP_STATE_DONE:
- case NM_DHCP_STATE_FAIL:
- dhcp6_fail(self, state);
- break;
- default:
- break;
- }
-}
-
-static void
-dhcp6_prefix_delegated(NMDhcpClient *client, NMPlatformIP6Address *prefix, gpointer user_data)
-{
- NMDevice *self = NM_DEVICE(user_data);
-
- /* Just re-emit. The device just contributes the prefix to the
- * pool in NMPolicy, which decides about subnet allocation
- * on the shared devices. */
- g_signal_emit(self, signals[IP6_PREFIX_DELEGATED], 0, prefix);
-}
-
-/*****************************************************************************/
-
-static gboolean
-dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMSettingIPConfig *s_ip6;
- gs_unref_bytes GBytes *hwaddr = NULL;
- gs_unref_bytes GBytes * duid = NULL;
- gboolean enforce_duid = FALSE;
- const NMPlatformLink * pllink;
- gs_free char * mud_url_free = NULL;
- GError * error = NULL;
- guint32 iaid;
- gboolean iaid_explicit;
- NMSettingConnection * s_con;
- const NMPlatformIP6Address *ll_addr = NULL;
-
- g_return_val_if_fail(connection, FALSE);
-
- s_ip6 = nm_connection_get_setting_ip6_config(connection);
- nm_assert(s_ip6);
- s_con = nm_connection_get_setting_connection(connection);
- nm_assert(s_con);
-
- if (priv->ext_ip6_config_captured) {
- ll_addr = nm_ip6_config_find_first_address(priv->ext_ip6_config_captured,
- NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
- | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL);
- }
-
- if (!ll_addr) {
- _LOGW(LOGD_DHCP6, "can't start DHCPv6: no link-local address");
- return FALSE;
- }
-
- pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self));
- if (pllink)
- hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address);
-
- iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET6, connection, TRUE, &iaid_explicit);
- duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, &enforce_duid);
-
- priv->dhcp_data_6.client = nm_dhcp_manager_start_ip6(
- nm_dhcp_manager_get(),
- nm_device_get_multi_index(self),
- nm_device_get_ip_iface(self),
- nm_device_get_ip_ifindex(self),
- &ll_addr->address,
- nm_connection_get_uuid(connection),
- nm_device_get_route_table(self, AF_INET6),
- nm_device_get_route_metric(self, AF_INET6),
- (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY
- : NM_DHCP_CLIENT_FLAGS_NONE,
- nm_setting_ip_config_get_dhcp_send_hostname(s_ip6),
- nm_setting_ip_config_get_dhcp_hostname(s_ip6),
- _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET6),
- _prop_get_connection_mud_url(self, s_con, &mud_url_free),
- duid,
- enforce_duid,
- iaid,
- iaid_explicit,
- _prop_get_ipvx_dhcp_timeout(self, AF_INET6),
- _device_get_dhcp_anycast_address(self),
- nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)),
- priv->dhcp6.needed_prefixes,
- &error);
- if (!priv->dhcp_data_6.client) {
- _LOGW(LOGD_DHCP6, "failure to start DHCPv6: %s", error->message);
- g_clear_error(&error);
- if (nm_device_sys_iface_state_is_external_or_assume(self))
- priv->dhcp_data_6.was_active = TRUE;
- return FALSE;
- }
-
- priv->dhcp_data_6.state_sigid = g_signal_connect(priv->dhcp_data_6.client,
- NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
- G_CALLBACK(dhcp6_state_changed),
- self);
- priv->dhcp6.prefix_sigid = g_signal_connect(priv->dhcp_data_6.client,
- NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED,
- G_CALLBACK(dhcp6_prefix_delegated),
- self);
-
- if (nm_device_sys_iface_state_is_external_or_assume(self))
- priv->dhcp_data_6.was_active = TRUE;
-
- return TRUE;
-}
-
-static gboolean
-dhcp6_start(NMDevice *self, gboolean wait_for_ll)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMConnection * connection;
-
- nm_dbus_object_clear_and_unexport(&priv->dhcp_data_6.config);
- priv->dhcp_data_6.config = nm_dhcp_config_new(AF_INET6);
-
- nm_assert(!applied_config_get_current(&priv->dhcp6.ip6_config));
- applied_config_clear(&priv->dhcp6.ip6_config);
- nm_clear_g_free(&priv->dhcp6.event_id);
-
- connection = nm_device_get_applied_connection(self);
- g_return_val_if_fail(connection, FALSE);
-
- if (wait_for_ll) {
- /* ensure link local is ready... */
- if (!linklocal6_start(self)) {
- /* wait for the LL address to show up */
- return TRUE;
- }
- /* already have the LL address; kick off DHCP */
- }
-
- if (!dhcp6_start_with_link_ready(self, connection))
- return FALSE;
-
- return TRUE;
-}
-
-gboolean
-nm_device_dhcp6_renew(NMDevice *self, gboolean release)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMNDiscDHCPLevel mode;
-
- g_return_val_if_fail(priv->dhcp_data_6.client != NULL, FALSE);
-
- _LOGI(LOGD_DHCP6, "DHCPv6 lease renewal requested");
-
- /* Terminate old DHCP instance and release the old lease */
- mode = priv->dhcp6.mode;
- dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, release);
- priv->dhcp6.mode = mode;
-
- /* Start DHCP again on the interface */
- return dhcp6_start(self, FALSE);
-}
-
-/*****************************************************************************/
/*
* Called on the requesting interface when a subnet can't be obtained
@@ -10023,7 +9530,7 @@ nm_device_request_ip6_prefixes(NMDevice *self, int needed_prefixes)
if (priv->dhcp_data_6.client) {
_LOGD(LOGD_IP6, "ipv6-pd: asking DHCPv6 for %d prefixes", needed_prefixes);
- nm_device_dhcp6_renew(self, FALSE);
+ nm_device_dhcp_renew(self, AF_INET6, FALSE);
} else {
_LOGI(LOGD_IP6, "ipv6-pd: device doesn't use DHCPv6, can't request prefixes");
}
@@ -10042,25 +9549,24 @@ nm_device_needs_ip6_subnet(NMDevice *self)
void
nm_device_use_ip6_subnet(NMDevice *self, const NMPlatformIP6Address *subnet)
{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMPlatformIP6Address address = *subnet;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ char sbuf[sizeof(_nm_utils_to_string_buffer)];
+ NMPlatformIP6Address address;
- if (!applied_config_get_current(&priv->ac_ip6_config))
- applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6);
+ l3cd = nm_device_create_l3_config_data(self);
/* Assign a ::1 address in the subnet for us. */
+ address = *subnet;
address.address.s6_addr32[3] |= htonl(1);
- applied_config_add_address(&priv->ac_ip6_config, NM_PLATFORM_IP_ADDRESS_CAST(&address));
+
+ nm_l3_config_data_add_address_6(l3cd, &address);
_LOGD(LOGD_IP6,
- "ipv6-pd: using %s address (preferred for %u seconds)",
- _nm_utils_inet6_ntop(&address.address, sbuf),
- subnet->preferred);
+ "ipv6-pd: using %s",
+ nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf)));
- /* This also updates the ndisc if there are actual changes. */
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "ipv6-pd: failed applying IP6 config for connection sharing");
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_PD_6, l3cd, FALSE);
+ _dev_l3_cfg_commit(self, TRUE);
}
/*
@@ -10070,41 +9576,47 @@ nm_device_use_ip6_subnet(NMDevice *self, const NMPlatformIP6Address *subnet)
void
nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMIP6Config * from_config = NULL;
- guint i, len;
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NMDevicePrivate * priv_src;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ const NML3ConfigData * l3cd_src;
+
+ /* FIXME(l3fcg): this entire code an approach seems flawed. It's flawed, because the
+ * very next RA will reset the changes. */
- if (applied_config_get_current(&priv->ac_ip6_config)) {
- applied_config_reset_nameservers(&priv->ac_ip6_config);
- applied_config_reset_searches(&priv->ac_ip6_config);
+ if (priv->l3cds[L3_CONFIG_DATA_TYPE_AC_6].d) {
+ l3cd = nm_l3_config_data_new_clone(priv->l3cds[L3_CONFIG_DATA_TYPE_AC_6].d, 0);
+ nm_l3_config_data_clear_nameservers(l3cd, AF_INET6);
+ nm_l3_config_data_clear_searches(l3cd, AF_INET6);
} else
- applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6);
+ l3cd = nm_device_create_l3_config_data(self);
- if (from_device)
- from_config = nm_device_get_ip6_config(from_device);
- if (!from_config)
- return;
+ priv_src = NM_DEVICE_GET_PRIVATE(from_device);
+ l3cd_src = priv_src->l3cds[L3_CONFIG_DATA_TYPE_AC_6].d;
+ if (l3cd_src) {
+ const char *const * strvarr;
+ const struct in6_addr *const *addrs;
+ guint n;
+ guint i;
- len = nm_ip6_config_get_num_nameservers(from_config);
- for (i = 0; i < len; i++) {
- applied_config_add_nameserver(
- &priv->ac_ip6_config,
- (const NMIPAddr *) nm_ip6_config_get_nameserver(from_config, i));
- }
+ addrs = nm_l3_config_data_get_nameservers(l3cd_src, AF_INET6, &n);
+ for (i = 0; i < n; i++)
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET6, addrs[i]);
- len = nm_ip6_config_get_num_searches(from_config);
- for (i = 0; i < len; i++) {
- applied_config_add_search(&priv->ac_ip6_config, nm_ip6_config_get_search(from_config, i));
+ strvarr = nm_l3_config_data_get_searches(l3cd_src, AF_INET6, &n);
+ for (i = 0; i < n; i++)
+ nm_l3_config_data_add_search(l3cd, AF_INET6, strvarr[i]);
}
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "ipv6-pd: failed applying DNS config for connection sharing");
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_AC_6, l3cd, FALSE);
+
+ _dev_l3_cfg_commit(self, TRUE);
}
/*****************************************************************************/
static void
-linklocal6_failed(NMDevice *self)
+_dev_ll6_failed(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
@@ -10113,17 +9625,18 @@ linklocal6_failed(NMDevice *self)
}
static gboolean
-linklocal6_timeout_cb(gpointer user_data)
+_dev_ll6_timeout_cb(gpointer user_data)
{
NMDevice *self = user_data;
_LOGD(LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout");
- linklocal6_failed(self);
+ _dev_ll6_failed(self);
return G_SOURCE_REMOVE;
}
-static void
-linklocal6_check_complete(NMDevice *self)
+//XXX
+_nm_unused static void
+_dev_ll6_check_complete(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
NMConnection * connection;
@@ -10134,18 +9647,18 @@ linklocal6_check_complete(NMDevice *self)
return;
}
- if (!priv->ext_ip6_config_captured
- || !nm_ip6_config_find_first_address(priv->ext_ip6_config_captured,
- NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
- | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) {
- /* we don't have a non-tentative link local address yet. Wait longer. */
- return;
- }
+ //XXX if ( !priv->ext_ip6_config_captured
+ //XXX || !nm_ip6_config_find_first_address (priv->ext_ip6_config_captured,
+ //XXX NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
+ //XXX | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) {
+ //XXX /* we don't have a non-tentative link local address yet. Wait longer. */
+ //XXX return;
+ //XXX }
nm_clear_g_source(&priv->linklocal6_timeout_id);
connection = nm_device_get_applied_connection(self);
- g_assert(connection);
+ g_return_if_fail(connection);
method = nm_device_get_effective_ip_config_method(self, AF_INET6);
@@ -10156,14 +9669,14 @@ linklocal6_check_complete(NMDevice *self)
if (NM_IN_STRSET(method,
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NM_SETTING_IP6_CONFIG_METHOD_SHARED))
- addrconf6_start_with_link_ready(self);
+ _dev_ac6_start(self);
else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
- if (!dhcp6_start_with_link_ready(self, connection)) {
+ if (!_dev_dhcpx_start(self, AF_INET6)) {
/* Time out IPv6 instead of failing the entire activation */
nm_device_activate_schedule_ip_config_timeout(self, AF_INET6);
}
} else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
+ nm_device_activate_schedule_ip_config_result(self, AF_INET6);
else
g_return_if_fail(FALSE);
}
@@ -10182,17 +9695,18 @@ check_and_add_ipv6ll_addr(NMDevice *self)
if (!priv->ipv6ll_handle)
return;
- if (priv->ext_ip6_config_captured
- && nm_ip6_config_find_first_address(priv->ext_ip6_config_captured,
- NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
- | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL
- | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) {
- /* Already have an LL address, nothing to do */
- return;
- }
+ //XXX if ( priv->ext_ip6_config_captured
+ //XXX && nm_ip6_config_find_first_address (priv->ext_ip6_config_captured,
+ //XXX NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
+ //XXX | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL
+ //XXX | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) {
+ //XXX /* Already have an LL address, nothing to do */
+ //XXX return;
+ //XXX }
priv->ipv6ll_has = FALSE;
memset(&priv->ipv6ll_addr, 0, sizeof(priv->ipv6ll_addr));
+ _dev_l3_set_l3cd_ll_6(self);
memset(&lladdr, 0, sizeof(lladdr));
lladdr.s6_addr16[0] = htons(0xfe80);
@@ -10216,7 +9730,7 @@ check_and_add_ipv6ll_addr(NMDevice *self)
&error)) {
_LOGW(LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
g_clear_error(&error);
- linklocal6_failed(self);
+ _dev_ll6_failed(self);
return;
}
addr_type = "stable-privacy";
@@ -10227,7 +9741,7 @@ check_and_add_ipv6ll_addr(NMDevice *self)
/* We already started and attempt to add a LL address. For the EUI-64
* mode we can't pick a new one, we'll just fail. */
_LOGW(LOGD_IP6, "linklocal6: DAD failed for an EUI-64 address");
- linklocal6_failed(self);
+ _dev_ll6_failed(self);
return;
}
@@ -10245,21 +9759,36 @@ check_and_add_ipv6ll_addr(NMDevice *self)
_nm_utils_inet6_ntop(&lladdr, sbuf));
priv->ipv6ll_has = TRUE;
priv->ipv6ll_addr = lladdr;
- ip_config_merge_and_apply(self, AF_INET6, TRUE);
+ _dev_l3_cfg_commit(self, TRUE);
}
static gboolean
-linklocal6_start(NMDevice *self)
+_dev_ll6_start(NMDevice *self, struct in6_addr *out_ll_addr)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ int ifindex;
- nm_clear_g_source(&priv->linklocal6_timeout_id);
+ ifindex = nm_device_get_ip_ifindex(self);
+ if (ifindex > 0) {
+ const NMPObject *plobj;
+ NMDedupMultiIter iter;
+ NMPLookup lookup;
+
+ nm_platform_iter_obj_for_each (
+ &iter,
+ nm_device_get_platform(self),
+ nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex),
+ &plobj) {
+ if (nm_platform_ip6_address_match(NMP_OBJECT_CAST_IP6_ADDRESS(plobj),
+ NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
+ | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) {
+ NM_SET_OUT(out_ll_addr, NMP_OBJECT_CAST_IP6_ADDRESS(plobj)->address);
+ return TRUE;
+ }
+ }
+ }
- if (priv->ext_ip6_config_captured
- && nm_ip6_config_find_first_address(priv->ext_ip6_config_captured,
- NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL
- | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL))
- return TRUE;
+ nm_clear_g_source(&priv->linklocal6_timeout_id);
_LOGD(LOGD_DEVICE,
"linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses "
@@ -10273,7 +9802,7 @@ linklocal6_start(NMDevice *self)
* FIXME: use dad/retrans sysctl values if they are higher than a minimum time.
* (rh #1101809)
*/
- priv->linklocal6_timeout_id = g_timeout_add_seconds(15, linklocal6_timeout_cb, self);
+ priv->linklocal6_timeout_id = g_timeout_add_seconds(15, _dev_ll6_timeout_cb, self);
return FALSE;
}
@@ -10437,13 +9966,16 @@ set_platform_mtu(NMDevice *self, guint32 mtu)
}
static void
-_commit_mtu(NMDevice *self, const NMIP4Config *config)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMDeviceMtuSource source = NM_DEVICE_MTU_SOURCE_NONE;
- guint32 ip6_mtu, ip6_mtu_orig;
- guint32 mtu_desired, mtu_desired_orig;
- guint32 mtu_plat;
+_commit_mtu(NMDevice *self)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NMDeviceMtuSource source = NM_DEVICE_MTU_SOURCE_NONE;
+ const NML3ConfigData *l3cd;
+ guint32 ip6_mtu_orig;
+ guint32 ip6_mtu;
+ guint32 mtu_desired_orig;
+ guint32 mtu_desired;
+ guint32 mtu_plat;
struct {
gboolean initialized;
guint32 value;
@@ -10451,7 +9983,9 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config)
0,
};
int ifindex;
- char sbuf[64], sbuf1[64], sbuf2[64];
+ char sbuf[64];
+ char sbuf1[64];
+ char sbuf2[64];
gboolean success = TRUE;
ifindex = nm_device_get_ip_ifindex(self);
@@ -10465,8 +9999,11 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config)
return;
}
+ l3cd = nm_l3cfg_get_combined_l3cd(priv->l3cfg, FALSE);
+
{
- guint32 mtu = 0;
+ guint32 mtu = 0;
+ guint32 mtu2;
gboolean force = FALSE;
/* We take the MTU from various sources: (in order of increasing
@@ -10493,9 +10030,9 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config)
if (NM_DEVICE_GET_CLASS(self)->get_configured_mtu)
mtu = NM_DEVICE_GET_CLASS(self)->get_configured_mtu(self, &source, &force);
- if (config && !force && source < NM_DEVICE_MTU_SOURCE_IP_CONFIG
- && nm_ip4_config_get_mtu(config)) {
- mtu = nm_ip4_config_get_mtu(config);
+ if (l3cd && !force && source < NM_DEVICE_MTU_SOURCE_IP_CONFIG
+ && (mtu2 = nm_l3_config_data_get_mtu(l3cd)) > 0) {
+ mtu = mtu2;
source = NM_DEVICE_MTU_SOURCE_IP_CONFIG;
}
@@ -10678,244 +10215,148 @@ nm_device_commit_mtu(NMDevice *self)
state = nm_device_get_state(self);
if (state >= NM_DEVICE_STATE_CONFIG && state < NM_DEVICE_STATE_DEACTIVATING) {
_LOGT(LOGD_DEVICE, "mtu: commit-mtu...");
- _commit_mtu(self, NM_DEVICE_GET_PRIVATE(self)->ip_config_4);
+ _commit_mtu(self);
} else
_LOGT(LOGD_DEVICE,
"mtu: commit-mtu... skip due to state %s",
nm_device_state_to_str(state));
}
+/*****************************************************************************/
+
static void
-ndisc_config_changed(NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, NMDevice *self)
+_dev_ac6_ndisc_config_changed(NMNDisc * ndisc,
+ const NMNDiscData *rdata,
+ guint changed_i,
+ NMDevice * self)
{
- NMNDiscConfigMap changed = changed_int;
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- guint i;
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ int ifindex;
- g_return_if_fail(priv->act_request.obj);
-
- if (!applied_config_get_current(&priv->ac_ip6_config))
- applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6);
-
- if (changed & NM_NDISC_CONFIG_ADDRESSES) {
- guint8 plen;
- guint32 ifa_flags;
-
- /* Check, whether kernel is recent enough to help user space handling RA.
- * If it's not supported, we have no ipv6-privacy and must add autoconf
- * addresses as /128. The reason for the /128 is to prevent the kernel
- * from adding a prefix route for this address. */
- ifa_flags = 0;
- if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) {
- ifa_flags |= IFA_F_NOPREFIXROUTE;
- if (NM_IN_SET(priv->ndisc_use_tempaddr,
- NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
- NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR))
- ifa_flags |= IFA_F_MANAGETEMPADDR;
- plen = 64;
- } else
- plen = 128;
-
- nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.orig,
- rdata->addresses,
- rdata->addresses_n,
- plen,
- ifa_flags);
- if (priv->ac_ip6_config.current) {
- nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.current,
- rdata->addresses,
- rdata->addresses_n,
- plen,
- ifa_flags);
- }
- }
-
- if (NM_FLAGS_ANY(changed, NM_NDISC_CONFIG_ROUTES | NM_NDISC_CONFIG_GATEWAYS)) {
- nm_ip6_config_reset_routes_ndisc(
- (NMIP6Config *) priv->ac_ip6_config.orig,
- rdata->gateways,
- rdata->gateways_n,
- rdata->routes,
- rdata->routes_n,
- nm_device_get_route_table(self, AF_INET6),
- nm_device_get_route_metric(self, AF_INET6),
- nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF));
- if (priv->ac_ip6_config.current) {
- nm_ip6_config_reset_routes_ndisc(
- (NMIP6Config *) priv->ac_ip6_config.current,
- rdata->gateways,
- rdata->gateways_n,
- rdata->routes,
- rdata->routes_n,
- nm_device_get_route_table(self, AF_INET6),
- nm_device_get_route_metric(self, AF_INET6),
- nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF));
- }
- }
-
- if (changed & NM_NDISC_CONFIG_DNS_SERVERS) {
- /* Rebuild DNS server list from neighbor discovery cache. */
- applied_config_reset_nameservers(&priv->ac_ip6_config);
-
- for (i = 0; i < rdata->dns_servers_n; i++)
- applied_config_add_nameserver(&priv->ac_ip6_config,
- (const NMIPAddr *) &rdata->dns_servers[i].address);
- }
+ ifindex = nm_device_get_ip_ifindex(self);
+ if (ifindex <= 0)
+ g_return_if_reached();
- if (changed & NM_NDISC_CONFIG_DNS_DOMAINS) {
- /* Rebuild domain list from neighbor discovery cache. */
- applied_config_reset_searches(&priv->ac_ip6_config);
+ l3cd = nm_ndisc_data_to_l3cd(
+ nm_device_get_multi_index(self),
+ ifindex,
+ rdata,
+ priv->ac6_ip6_privacy,
+ nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF),
+ nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS));
- for (i = 0; i < rdata->dns_domains_n; i++)
- applied_config_add_search(&priv->ac_ip6_config, rdata->dns_domains[i].domain);
- }
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_AC_6, l3cd, FALSE);
- if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) {
- dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, TRUE);
+ _dev_dhcp6_set_dhcp_level(self, rdata->dhcp_level);
- priv->dhcp6.mode = rdata->dhcp_level;
- if (priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE) {
- _LOGD(LOGD_DEVICE | LOGD_DHCP6,
- "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6"
- " as requested by IPv6 router...");
- if (!dhcp6_start(self, FALSE)) {
- if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) {
- nm_device_state_changed(self,
- NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_DHCP_START_FAILED);
- return;
- }
- }
- }
- }
+ _dev_l3_cfg_commit(self, TRUE);
+}
- if (changed & NM_NDISC_CONFIG_HOP_LIMIT)
- nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(nm_device_get_platform(self),
- nm_device_get_ip_iface(self),
- rdata->hop_limit);
+static void
+_dev_ac6_handle_timeout(NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) {
- nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(nm_device_get_platform(self),
- nm_device_get_ip_iface(self),
- rdata->reachable_time_ms);
- }
+ _LOGD(LOGD_IP6, "ac6: timeout for autoconf (IPv6 router advertisement) reached");
- if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) {
- nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(nm_device_get_platform(self),
- nm_device_get_ip_iface(self),
- rdata->retrans_timer_ms);
- }
+ nm_clear_g_source_inst(&priv->ac6_ndisc_grace_source);
+ priv->ac6_ndisc_grace_pending = FALSE;
+ _set_ip_state_check(self, AF_INET6);
+}
- if (changed & NM_NDISC_CONFIG_MTU) {
- if (priv->ip6_mtu != rdata->mtu) {
- _LOGD(LOGD_DEVICE, "mtu: set IPv6 MTU to %u", (guint) rdata->mtu);
- priv->ip6_mtu = rdata->mtu;
- }
- }
+static void
+_dev_ac6_ndisc_ra_timeout(NMNDisc *ndisc, NMDevice *self)
+{
+ _dev_ac6_handle_timeout(self);
+}
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
+static gboolean
+_dev_ac6_grace_period_expired(gpointer user_data)
+{
+ _dev_ac6_handle_timeout(user_data);
+ return G_SOURCE_REMOVE;
}
-static void
-ndisc_ra_timeout(NMNDisc *ndisc, NMDevice *self)
+static gboolean
+_dev_ac6_grace_period_start(NMDevice *self, guint32 timeout_sec, gboolean force_restart)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- /* We don't want to stop listening for router advertisements completely,
- * but instead let device activation continue activating. If an RA
- * shows up later, we'll use it as long as the device is not disconnected.
+ /* In any other case (expired lease, assumed connection, etc.),
+ * wait for some time before failing the IP method.
*/
-
- _LOGD(LOGD_IP6, "timed out waiting for IPv6 router advertisement");
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) {
- /* If RA is our only source of addressing information and we don't
- * ever receive one, then time out IPv6. But if there is other
- * IPv6 configuration, like manual IPv6 addresses or external IPv6
- * config, consider that sufficient for IPv6 success.
- *
- * FIXME: it doesn't seem correct to determine this based on which
- * addresses we find inside priv->ip_config_6.
- */
- if (priv->ip_config_6
- && nm_ip6_config_find_first_address(priv->ip_config_6,
- NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL
- | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY))
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
- else
- nm_device_activate_schedule_ip_config_timeout(self, AF_INET6);
+ if (!force_restart && priv->ac6_ndisc_grace_pending) {
+ /* already pending. */
+ return FALSE;
}
-}
-static void
-addrconf6_start_with_link_ready(NMDevice *self)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMUtilsIPv6IfaceId iid;
+ /* Start a grace period equal to the RA timeout multiplied
+ * by a constant factor. */
- g_assert(priv->ndisc);
+ nm_clear_g_source_inst(&priv->ac6_ndisc_grace_source);
- if (nm_device_get_ip_iface_identifier(self, &iid, FALSE)) {
- _LOGD(LOGD_IP6, "addrconf6: using the device EUI-64 identifier");
- nm_ndisc_set_iid(priv->ndisc, iid);
- } else {
- /* Don't abort the addrconf at this point -- if ndisc needs the iid
- * it will notice this itself. */
- _LOGI(LOGD_IP6, "addrconf6: no interface identifier; IPv6 address creation may fail");
+ if (timeout_sec == 0) {
+ priv->ac6_ndisc_grace_pending = FALSE;
+ return FALSE;
}
- /* Apply any manual configuration before starting RA */
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "failed to apply manual IPv6 configuration");
+ nm_assert(timeout_sec <= G_MAXINT32);
- if (nm_ndisc_get_node_type(priv->ndisc) == NM_NDISC_NODE_TYPE_ROUTER) {
- nm_device_sysctl_ip_conf_set(self, AF_INET6, "forwarding", "1");
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
- priv->needs_ip6_subnet = TRUE;
- g_signal_emit(self, signals[IP6_SUBNET_NEEDED], 0);
- }
+ if (timeout_sec == NM_RA_TIMEOUT_INFINITY)
+ _LOGD(LOGD_IP6, "ac6: grace period is infinity");
+ else {
+ guint timeout_msec;
- priv->ndisc_changed_id = g_signal_connect(priv->ndisc,
- NM_NDISC_CONFIG_RECEIVED,
- G_CALLBACK(ndisc_config_changed),
- self);
- priv->ndisc_timeout_id = g_signal_connect(priv->ndisc,
- NM_NDISC_RA_TIMEOUT_SIGNAL,
- G_CALLBACK(ndisc_ra_timeout),
- self);
+ _LOGD(LOGD_IP6, "ac6: grace period is %u seconds", timeout_sec);
- ndisc_set_router_config(priv->ndisc, self);
- nm_ndisc_start(priv->ndisc);
- priv->ndisc_started = TRUE;
- return;
+ if (timeout_sec < G_MAXUINT / (GRACE_PERIOD_MULTIPLIER * 1000u))
+ timeout_msec = timeout_sec * (GRACE_PERIOD_MULTIPLIER * 1000u);
+ else
+ timeout_msec = G_MAXUINT;
+
+ priv->ac6_ndisc_grace_source =
+ nm_g_source_attach(nm_g_timeout_source_new(timeout_msec,
+ G_PRIORITY_DEFAULT,
+ _dev_ac6_grace_period_expired,
+ self,
+ NULL),
+ NULL);
+ }
+
+ priv->ac6_ndisc_grace_pending = TRUE;
+ return TRUE;
}
static gboolean
-addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
+_dev_ac6_start(NMDevice *self)
{
NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NMSettingIP6Config *s_ip;
NMConnection * connection;
- NMSettingIP6Config *s_ip6 = NULL;
- GError * error = NULL;
- NMUtilsStableType stable_type;
- const char * stable_id;
- NMNDiscNodeType node_type;
- int max_addresses;
- int router_solicitations;
- int router_solicitation_interval;
- guint32 ra_timeout;
- guint32 default_ra_timeout;
+ gs_free_error GError *error = NULL;
+ NMUtilsStableType stable_type;
+ NMNDiscNodeType node_type;
+ const char * stable_id;
+ int max_addresses;
+ int router_solicitations;
+ int router_solicitation_interval;
+ guint32 ra_timeout;
+ guint32 default_ra_timeout;
+ NMUtilsIPv6IfaceId iid;
connection = nm_device_get_applied_connection(self);
- g_assert(connection);
-
- nm_assert(!applied_config_get_current(&priv->ac_ip6_config));
- applied_config_clear(&priv->ac_ip6_config);
+ nm_assert(connection);
+ s_ip = NM_SETTING_IP6_CONFIG(nm_connection_get_setting_ip6_config(connection));
+ nm_assert(s_ip);
- nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref);
- nm_clear_g_source(&priv->rt6_temporary_not_available_id);
+ priv->ac6_ndisc_started = TRUE;
- s_ip6 = NM_SETTING_IP6_CONFIG(nm_connection_get_setting_ip6_config(connection));
- g_assert(s_ip6);
+ if (!_dev_ll6_start(self, NULL)) {
+ /* wait for the LL address to show up */
+ _dev_ac6_grace_period_start(self, 30, TRUE);
+ return TRUE;
+ }
if (nm_streq(nm_device_get_effective_ip_config_method(self, AF_INET6),
NM_SETTING_IP4_CONFIG_METHOD_SHARED))
@@ -10938,28 +10379,30 @@ addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
ra_timeout = default_ra_timeout;
}
- stable_id = _prop_get_connection_stable_id(self, connection, &stable_type);
- priv->ndisc = nm_lndp_ndisc_new(nm_device_get_platform(self),
- nm_device_get_ip_ifindex(self),
- nm_device_get_ip_iface(self),
- stable_type,
- stable_id,
- nm_setting_ip6_config_get_addr_gen_mode(s_ip6),
- node_type,
- max_addresses,
- router_solicitations,
- router_solicitation_interval,
- ra_timeout,
- &error);
- if (!priv->ndisc) {
+ _dev_ac6_grace_period_start(self, ra_timeout, TRUE);
+
+ stable_id = _prop_get_connection_stable_id(self, connection, &stable_type);
+
+ priv->ac6_ndisc = nm_lndp_ndisc_new(nm_device_get_platform(self),
+ nm_device_get_ip_ifindex(self),
+ nm_device_get_ip_iface(self),
+ stable_type,
+ stable_id,
+ nm_setting_ip6_config_get_addr_gen_mode(s_ip),
+ node_type,
+ max_addresses,
+ router_solicitations,
+ router_solicitation_interval,
+ ra_timeout,
+ &error);
+ if (!priv->ac6_ndisc) {
_LOGE(LOGD_IP6, "addrconf6: failed to start neighbor discovery: %s", error->message);
- g_error_free(error);
return FALSE;
}
- priv->ndisc_use_tempaddr = use_tempaddr;
+ priv->ac6_ip6_privacy = _prop_get_ipv6_ip6_privacy(self);
- if (NM_IN_SET(use_tempaddr,
+ if (NM_IN_SET(priv->ac6_ip6_privacy,
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
&& !nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) {
@@ -10968,32 +10411,58 @@ addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
"IPv6 private addresses. This feature is not available");
}
- /* ensure link local is ready... */
- if (!linklocal6_start(self)) {
- /* wait for the LL address to show up */
- return TRUE;
+ if (nm_device_get_ip_iface_identifier(self, &iid, FALSE)) {
+ _LOGD(LOGD_IP6, "addrconf6: using the device EUI-64 identifier");
+ nm_ndisc_set_iid(priv->ac6_ndisc, iid);
+ } else {
+ /* Don't abort the addrconf at this point -- if ndisc needs the iid
+ * it will notice this itself. */
+ _LOGD(LOGD_IP6, "addrconf6: no interface identifier; IPv6 address creation may fail");
}
- /* already have the LL address; kick off neighbor discovery */
- addrconf6_start_with_link_ready(self);
+ _dev_l3_cfg_commit(self, TRUE);
+
+ if (nm_ndisc_get_node_type(priv->ac6_ndisc) == NM_NDISC_NODE_TYPE_ROUTER) {
+ nm_device_sysctl_ip_conf_set(self, AF_INET6, "forwarding", "1");
+ nm_device_activate_schedule_ip_config_result(self, AF_INET6);
+ priv->needs_ip6_subnet = TRUE;
+ g_signal_emit(self, signals[IP6_SUBNET_NEEDED], 0);
+ }
+
+ priv->ac6_ndisc_changed_id = g_signal_connect(priv->ac6_ndisc,
+ NM_NDISC_CONFIG_RECEIVED,
+ G_CALLBACK(_dev_ac6_ndisc_config_changed),
+ self);
+ priv->ac6_ndisc_timeout_id = g_signal_connect(priv->ac6_ndisc,
+ NM_NDISC_RA_TIMEOUT_SIGNAL,
+ G_CALLBACK(_dev_ac6_ndisc_ra_timeout),
+ self);
+
+ _dev_ac6_ndisc_set_router_config(self);
+
+ nm_ndisc_start(priv->ac6_ndisc);
+
+ priv->ac6_ndisc_started = TRUE;
+
return TRUE;
}
static void
-addrconf6_cleanup(NMDevice *self)
+_dev_ac6_cleanup(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- priv->ndisc_started = FALSE;
- nm_clear_g_signal_handler(priv->ndisc, &priv->ndisc_changed_id);
- nm_clear_g_signal_handler(priv->ndisc, &priv->ndisc_timeout_id);
+ priv->ac6_ndisc_started = FALSE;
+ priv->ac6_ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
+
+ nm_clear_g_signal_handler(priv->ac6_ndisc, &priv->ac6_ndisc_changed_id);
+ nm_clear_g_signal_handler(priv->ac6_ndisc, &priv->ac6_ndisc_timeout_id);
+
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_AC_6, NULL, FALSE);
- applied_config_clear(&priv->ac_ip6_config);
- nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref);
- nm_clear_g_source(&priv->rt6_temporary_not_available_id);
- if (priv->ndisc) {
- nm_ndisc_stop(priv->ndisc);
- g_clear_object(&priv->ndisc);
+ if (priv->ac6_ndisc) {
+ nm_ndisc_stop(priv->ac6_ndisc);
+ g_clear_object(&priv->ac6_ndisc);
}
}
@@ -11115,10 +10584,10 @@ ip_requires_slaves(NMDevice *self, int addr_family)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * self,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * self,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
const int IS_IPv4 = NM_IS_IPv4(addr_family);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
@@ -11167,52 +10636,34 @@ act_stage3_ip_config_start(NMDevice * self,
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
NMSettingIPConfig *s_ip4;
- NMIP4Config ** configs, *config;
guint num_addresses;
+ /* FIXME(l3cfg) */
s_ip4 = nm_connection_get_setting_ip4_config(connection);
g_return_val_if_fail(s_ip4, NM_ACT_STAGE_RETURN_FAILURE);
num_addresses = nm_setting_ip_config_get_num_addresses(s_ip4);
if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
- ret = dhcp4_start(self);
- if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
+ if (!_dev_dhcpx_start(self, AF_INET)) {
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED);
- return ret;
+ return NM_ACT_STAGE_RETURN_FAILURE;
}
- } else {
+ } else
g_return_val_if_fail(num_addresses != 0, NM_ACT_STAGE_RETURN_FAILURE);
- ret = NM_ACT_STAGE_RETURN_POSTPONE;
- }
-
- if (num_addresses) {
- config = nm_device_ip4_config_new(self);
- nm_ip4_config_merge_setting(config,
- nm_connection_get_setting_ip4_config(connection),
- NM_SETTING_CONNECTION_MDNS_DEFAULT,
- NM_SETTING_CONNECTION_LLMNR_DEFAULT,
- nm_device_get_route_table(self, AF_INET),
- nm_device_get_route_metric(self, AF_INET));
- configs = g_new0(NMIP4Config *, 2);
- configs[0] = config;
- ipv4_dad_start(self, configs, ipv4_manual_method_apply);
- }
+ ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) {
- ret = ipv4ll_start(self);
+ ret = _dev_ll4_start(self);
if (ret == NM_ACT_STAGE_RETURN_FAILURE)
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED);
} else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
- if (out_config) {
- *out_config = shared4_new_config(self, connection);
- if (*out_config) {
- priv->dnsmasq_manager = nm_dnsmasq_manager_new(nm_device_get_ip_iface(self));
- ret = NM_ACT_STAGE_RETURN_SUCCESS;
- } else {
- NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
- ret = NM_ACT_STAGE_RETURN_FAILURE;
- }
- } else
- g_return_val_if_reached(NM_ACT_STAGE_RETURN_FAILURE);
+ gs_free_error GError *error = NULL;
+
+ if (!_dev_shared4_start(self, &error)) {
+ _LOGW(LOGD_SHARING, "Activation: start sharing failed: %s", error->message);
+ NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+ ret = NM_ACT_STAGE_RETURN_SUCCESS;
} else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
ret = NM_ACT_STAGE_RETURN_SUCCESS;
else
@@ -11220,10 +10671,7 @@ act_stage3_ip_config_start(NMDevice * self,
return ret;
} else {
- NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
- const char * ip6_privacy_str = "0";
- NMPlatform * platform;
- int ifindex;
+ int ifindex;
if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) {
nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", "1");
@@ -11241,15 +10689,12 @@ act_stage3_ip_config_start(NMDevice * self,
* slave should not depend on the previous state. Flush
* addresses and routes on activation.
*/
- ifindex = nm_device_get_ip_ifindex(self);
- platform = nm_device_get_platform(self);
-
+ ifindex = nm_device_get_ip_ifindex(self);
if (ifindex > 0) {
- gs_unref_object NMIP6Config *config = nm_device_ip6_config_new(self);
-
- nm_platform_ip_route_flush(platform, AF_INET6, ifindex);
- nm_platform_ip_address_flush(platform, AF_INET6, ifindex);
- nm_device_set_ip_config(self, AF_INET6, (NMIPConfig *) config, FALSE, NULL);
+ nm_platform_ip_route_flush(nm_device_get_platform(self), AF_INET6, ifindex);
+ nm_platform_ip_address_flush(nm_device_get_platform(self),
+ AF_INET6,
+ ifindex);
}
} else {
gboolean ipv6ll_handle_old = priv->ipv6ll_handle;
@@ -11271,7 +10716,7 @@ act_stage3_ip_config_start(NMDevice * self,
* expose any ipv6 sysctls or allow presence of any addresses on the interface,
* including LL, which * would make it impossible to autoconfigure MTU to a
* correct value. */
- _commit_mtu(self, priv->ip_config_4);
+ _commit_mtu(self);
/* Any method past this point requires an IPv6LL address. Use NM-controlled
* IPv6LL if this is not an assumed connection, since assumed connections
@@ -11285,33 +10730,30 @@ act_stage3_ip_config_start(NMDevice * self,
set_disable_ipv6(self, "0");
/* Synchronize external IPv6 configuration with kernel, since
- * linklocal6_start() uses the information there to determine if we can
+ * _dev_ll6_start() uses the information there to determine if we can
* proceed with the selected method (SLAAC, DHCP, link-local).
*/
nm_platform_process_events(nm_device_get_platform(self));
- g_clear_object(&priv->ext_ip6_config_captured);
- priv->ext_ip6_config_captured =
- nm_ip6_config_capture(nm_device_get_multi_index(self),
- nm_device_get_platform(self),
- nm_device_get_ip_ifindex(self),
- NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
-
- ip6_privacy = _prop_get_ipv6_ip6_privacy(self);
+ //XXX g_clear_object (&priv->ext_ip6_config_captured);
+ //XXX priv->ext_ip6_config_captured = nm_ip6_config_capture (nm_device_get_multi_index (self),
+ //XXX nm_device_get_platform (self),
+ //XXX nm_device_get_ip_ifindex (self),
+ //XXX NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
if (NM_IN_STRSET(method,
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
- if (!addrconf6_start(self, ip6_privacy)) {
+ if (!_dev_ac6_start(self)) {
/* IPv6 might be disabled; allow IPv4 to proceed */
ret = NM_ACT_STAGE_RETURN_IP_FAIL;
} else
ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
- ret =
- linklocal6_start(self) ? NM_ACT_STAGE_RETURN_SUCCESS : NM_ACT_STAGE_RETURN_POSTPONE;
+ ret = _dev_ll6_start(self, NULL) ? NM_ACT_STAGE_RETURN_SUCCESS
+ : NM_ACT_STAGE_RETURN_POSTPONE;
} else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_MANAGED;
- if (!dhcp6_start(self, TRUE)) {
+ if (!_dev_dhcpx_start(self, AF_INET6)) {
/* IPv6 might be disabled; allow IPv4 to proceed */
ret = NM_ACT_STAGE_RETURN_IP_FAIL;
} else
@@ -11321,23 +10763,6 @@ act_stage3_ip_config_start(NMDevice * self,
else
_LOGW(LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
- if (ret != NM_ACT_STAGE_RETURN_FAILURE
- && !nm_device_sys_iface_state_is_external_or_assume(self)) {
- switch (ip6_privacy) {
- case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
- case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
- ip6_privacy_str = "0";
- break;
- case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
- ip6_privacy_str = "1";
- break;
- case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
- ip6_privacy_str = "2";
- break;
- }
- nm_device_sysctl_ip_conf_set(self, AF_INET6, "use_tempaddr", ip6_privacy_str);
- }
-
return ret;
}
}
@@ -11345,13 +10770,13 @@ act_stage3_ip_config_start(NMDevice * self,
gboolean
nm_device_activate_stage3_ip_start(NMDevice *self, int addr_family)
{
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMActStageReturn ret;
- NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
- gs_unref_object NMIPConfig *ip_config = NULL;
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NMActStageReturn ret;
+ NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
- g_assert(priv->ip_state_x[IS_IPv4] == NM_DEVICE_IP_STATE_WAIT);
+ g_return_val_if_fail(priv->ip_state_x[IS_IPv4] == NM_DEVICE_IP_STATE_WAIT, FALSE);
if (nm_device_sys_iface_state_is_external(self)) {
_set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_DONE);
@@ -11363,22 +10788,13 @@ nm_device_activate_stage3_ip_start(NMDevice *self, int addr_family)
ret = NM_DEVICE_GET_CLASS(self)->act_stage3_ip_config_start(self,
addr_family,
- (gpointer *) &ip_config,
+ &l3cd,
&failure_reason);
switch (ret) {
case NM_ACT_STAGE_RETURN_SUCCESS:
- if (!IS_IPv4) {
- /* Here we get a static IPv6 config, like for Shared where it's
- * autogenerated or from modems where it comes from ModemManager.
- */
- if (!ip_config)
- ip_config = nm_device_ip_config_new(self, addr_family);
- nm_assert(!applied_config_get_current(&priv->ac_ip6_config));
- applied_config_init(&priv->ac_ip6_config, ip_config);
- ip_config = NULL;
- }
- nm_device_activate_schedule_ip_config_result(self, addr_family, ip_config);
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_DEV_X(IS_IPv4), l3cd, FALSE);
+ nm_device_activate_schedule_ip_config_result(self, addr_family);
break;
case NM_ACT_STAGE_RETURN_IP_DONE:
_set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_DONE);
@@ -11435,9 +10851,6 @@ activate_stage3_ip_config_start(NMDevice *self)
&& !nm_device_activate_stage3_ip_start(self, AF_INET6))
return;
- /* Proxy */
- nm_device_set_proxy_config(self, NULL);
-
check_ip_state(self, TRUE, TRUE);
}
@@ -11628,8 +11041,66 @@ nm_device_activate_schedule_ip_config_timeout(NMDevice *self, int addr_family)
addr_family);
}
+/*****************************************************************************/
+
+static const NML3ConfigData *
+_dev_shared4_new_l3cd(NMDevice *self, NMConnection *connection, NMPlatformIP4Address *out_addr4)
+{
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMSettingIPConfig * s_ip4;
+ NMPlatformIP4Address address = {
+ .addr_source = NM_IP_CONFIG_SOURCE_SHARED,
+ };
+
+ g_return_val_if_fail(self, NULL);
+ g_return_val_if_fail(connection, NULL);
+
+ s_ip4 = nm_connection_get_setting_ip4_config(connection);
+ if (s_ip4 && nm_setting_ip_config_get_num_addresses(s_ip4) > 0) {
+ /* Use the first user-supplied address */
+ NMIPAddress *user = nm_setting_ip_config_get_address(s_ip4, 0);
+ in_addr_t a;
+
+ nm_ip_address_get_address_binary(user, &a);
+ nm_platform_ip4_address_set_addr(&address, a, nm_ip_address_get_prefix(user));
+ nm_clear_pointer(&priv->shared4_ip_handle, nm_netns_shared_ip_release);
+ } else {
+ if (!priv->shared4_ip_handle)
+ priv->shared4_ip_handle = nm_netns_shared_ip_reserve(nm_device_get_netns(self));
+ nm_platform_ip4_address_set_addr(&address, priv->shared4_ip_handle->addr, 24);
+ }
+
+ l3cd = nm_device_create_l3_config_data(self);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_SHARED);
+ nm_l3_config_data_add_address_4(l3cd, &address);
+
+ NM_SET_OUT(out_addr4, address);
+
+ return nm_l3_config_data_seal(g_steal_pointer(&l3cd));
+}
+
+static void
+_dev_shared4_cleanup(NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+
+ if (priv->shared4_dnsmasq_manager) {
+ nm_clear_g_signal_handler(priv->shared4_dnsmasq_manager, &priv->shared4_dnsmasq_state_id);
+ nm_dnsmasq_manager_stop(priv->shared4_dnsmasq_manager);
+ g_clear_object(&priv->shared4_dnsmasq_manager);
+ }
+
+ if (priv->firewall_config) {
+ nm_firewall_config_apply(priv->firewall_config, FALSE);
+ nm_clear_pointer(&priv->firewall_config, nm_firewall_config_free);
+ }
+
+ nm_clear_pointer(&priv->shared4_ip_handle, nm_netns_shared_ip_release);
+}
+
static gboolean
-share_init(NMDevice *self, GError **error)
+_dev_shared4_init(NMDevice *self, GError **error)
{
const char *const modules[] = {"ip_tables",
"iptable_nat",
@@ -11684,29 +11155,37 @@ share_init(NMDevice *self, GError **error)
return TRUE;
}
-static gboolean
-start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
+static void
+_dev_shared4_dnsmasq_state_changed_cb(NMDnsMasqManager *manager, guint status, gpointer user_data)
{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMActRequest * req;
- const NMPlatformIP4Address *ip4_addr = NULL;
- const char * ip_iface;
- GError * local = NULL;
- NMConnection * conn;
- NMSettingConnection * s_con;
- gboolean announce_android_metered;
- NMFirewallConfig * firewall_config;
-
- g_return_val_if_fail(config, FALSE);
+ NMDevice *self = NM_DEVICE(user_data);
- ip_iface = nm_device_get_ip_iface(self);
- if (!ip_iface) {
- g_set_error(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "device has no ip interface");
- return FALSE;
- }
+ if (status == NM_DNSMASQ_STATUS_DEAD)
+ nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
+}
- ip4_addr = nm_ip4_config_get_first_address(config);
- if (!ip4_addr || !ip4_addr->address) {
+static gboolean
+_dev_shared4_start(NMDevice *self, GError **error)
+{
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ NMPlatformIP4Address ip4_addr;
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
+ NMActRequest * req;
+ const char * ip_iface;
+ GError * local = NULL;
+ NMConnection * conn;
+ NMSettingConnection * s_con;
+ gboolean announce_android_metered;
+ NMConnection * applied;
+
+ nm_assert(!priv->firewall_config);
+ nm_assert(!priv->shared4_dnsmasq_manager);
+ nm_assert(priv->shared4_dnsmasq_state_id == 0);
+
+ applied = nm_device_get_applied_connection(self);
+
+ l3cd = _dev_shared4_new_l3cd(self, applied, &ip4_addr);
+ if (!l3cd) {
g_set_error(error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
@@ -11714,15 +11193,18 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
return FALSE;
}
- if (!share_init(self, error))
+ if (!_dev_shared4_init(self, error))
return FALSE;
+ ip_iface = nm_device_get_ip_iface(self);
+ g_return_val_if_fail(ip_iface, FALSE);
+
req = nm_device_get_act_request(self);
g_return_val_if_fail(req, FALSE);
- firewall_config = nm_firewall_config_new(ip_iface, ip4_addr->address, ip4_addr->plen);
+ priv->firewall_config = nm_firewall_config_new(ip_iface, ip4_addr.address, ip4_addr.plen);
- nm_act_request_set_shared(req, firewall_config);
+ nm_firewall_config_apply(priv->firewall_config, TRUE);
conn = nm_act_request_get_applied_connection(req);
s_con = nm_connection_get_setting_connection(conn);
@@ -11747,8 +11229,10 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
break;
}
- if (!nm_dnsmasq_manager_start(priv->dnsmasq_manager,
- config,
+ priv->shared4_dnsmasq_manager = nm_dnsmasq_manager_new(nm_device_get_ip_iface(self));
+
+ if (!nm_dnsmasq_manager_start(priv->shared4_dnsmasq_manager,
+ l3cd,
announce_android_metered,
&local)) {
g_set_error(error,
@@ -11756,81 +11240,29 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
NM_UTILS_ERROR_UNKNOWN,
"could not start dnsmasq due to %s",
local->message);
- g_error_free(local);
- nm_act_request_set_shared(req, NULL);
+ g_clear_error(&local);
+ _dev_shared4_cleanup(self);
return FALSE;
}
- priv->dnsmasq_state_id = g_signal_connect(priv->dnsmasq_manager,
- NM_DNS_MASQ_MANAGER_STATE_CHANGED,
- G_CALLBACK(dnsmasq_state_changed_cb),
- self);
- return TRUE;
-}
+ priv->shared4_dnsmasq_state_id =
+ g_signal_connect(priv->shared4_dnsmasq_manager,
+ NM_DNS_MASQ_MANAGER_STATE_CHANGED,
+ G_CALLBACK(_dev_shared4_dnsmasq_state_changed_cb),
+ self);
-static void
-arp_cleanup(NMDevice *self)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_SHARED_4, l3cd, FALSE);
- nm_clear_pointer(&priv->acd.announcing, nm_acd_manager_free);
-}
-
-void
-nm_device_arp_announce(NMDevice *self)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- NMConnection * connection;
- NMSettingIPConfig *s_ip4;
- guint num, i;
- const guint8 * hw_addr;
- size_t hw_addr_len = 0;
-
- arp_cleanup(self);
-
- hw_addr = nm_platform_link_get_address(nm_device_get_platform(self),
- nm_device_get_ip_ifindex(self),
- &hw_addr_len);
-
- if (!hw_addr || hw_addr_len != ETH_ALEN)
- return;
-
- /* We only care about manually-configured addresses; DHCP- and autoip-configured
- * ones should already have been seen on the network at this point.
- */
- connection = nm_device_get_applied_connection(self);
- if (!connection)
- return;
- s_ip4 = nm_connection_get_setting_ip4_config(connection);
- if (!s_ip4)
- return;
- num = nm_setting_ip_config_get_num_addresses(s_ip4);
- if (num == 0)
- return;
-
- priv->acd.announcing =
- nm_acd_manager_new(nm_device_get_ip_ifindex(self), hw_addr, hw_addr_len, NULL, NULL);
-
- for (i = 0; i < num; i++) {
- NMIPAddress *ip = nm_setting_ip_config_get_address(s_ip4, i);
- in_addr_t addr;
-
- if (inet_pton(AF_INET, nm_ip_address_get_address(ip), &addr) == 1)
- nm_acd_manager_add_address(priv->acd.announcing, addr);
- else
- g_warn_if_reached();
- }
-
- nm_acd_manager_announce_addresses(priv->acd.announcing);
+ return TRUE;
}
static void
activate_stage5_ip_config_result_x(NMDevice *self, int addr_family)
{
+#if 0 //XXX
const int IS_IPv4 = NM_IS_IPv4(addr_family);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
NMActRequest * req;
- const char * method;
int ip_ifindex;
int errsv;
gboolean do_announce = FALSE;
@@ -11991,6 +11423,7 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family)
_set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_DONE);
check_ip_state(self, FALSE, TRUE);
}
+#endif
}
static void
@@ -12010,18 +11443,18 @@ activate_stage5_ip_config_result_6(NMDevice *self)
: activate_stage5_ip_config_result_6)
void
-nm_device_activate_schedule_ip_config_result(NMDevice *self, int addr_family, NMIPConfig *config)
+nm_device_activate_schedule_ip_config_result(NMDevice *self, int addr_family)
{
NMDevicePrivate *priv;
const int IS_IPv4 = NM_IS_IPv4(addr_family);
g_return_if_fail(NM_IS_DEVICE(self));
- g_return_if_fail(!config || (IS_IPv4 && nm_ip_config_get_addr_family(config) == AF_INET));
+ g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6));
priv = NM_DEVICE_GET_PRIVATE(self);
if (IS_IPv4) {
- applied_config_init(&priv->dev_ip_config_4, config);
+ /* FIXME(l3cfg): surely there is something to do here? */
} else {
/* If IP had previously failed, move it back to NM_DEVICE_IP_STATE_CONF since we
* clearly now have configuration.
@@ -12046,73 +11479,6 @@ nm_device_activate_get_ip_state(NMDevice *self, int addr_family)
return NM_DEVICE_GET_PRIVATE(self)->ip_state_x[IS_IPv4];
}
-static void
-dad6_add_pending_address(NMDevice * self,
- NMPlatform * platform,
- int ifindex,
- const struct in6_addr *address,
- NMIP6Config ** dad6_config)
-{
- const NMPlatformIP6Address *pl_addr;
-
- pl_addr = nm_platform_ip6_address_get(platform, ifindex, address);
- if (pl_addr && NM_FLAGS_HAS(pl_addr->n_ifa_flags, IFA_F_TENTATIVE)
- && !NM_FLAGS_HAS(pl_addr->n_ifa_flags, IFA_F_DADFAILED)
- && !NM_FLAGS_HAS(pl_addr->n_ifa_flags, IFA_F_OPTIMISTIC)) {
- _LOGt(LOGD_DEVICE,
- "IPv6 DAD: pending address %s",
- nm_platform_ip6_address_to_string(pl_addr, NULL, 0));
-
- if (!*dad6_config)
- *dad6_config = nm_device_ip6_config_new(self);
-
- nm_ip6_config_add_address(*dad6_config, pl_addr);
- }
-}
-
-/*
- * Returns a NMIP6Config containing NM-configured addresses which
- * have the tentative flag, or NULL if none is present.
- */
-static NMIP6Config *
-dad6_get_pending_addresses(NMDevice *self)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMIP6Config * confs[] = {(NMIP6Config *) applied_config_get_current(&priv->ac_ip6_config),
- (NMIP6Config *) applied_config_get_current(&priv->dhcp6.ip6_config),
- priv->con_ip_config_6,
- (NMIP6Config *) applied_config_get_current(&priv->dev2_ip_config_6)};
- const NMPlatformIP6Address *addr;
- NMIP6Config * dad6_config = NULL;
- NMDedupMultiIter ipconf_iter;
- guint i;
- int ifindex;
- NMPlatform * platform;
-
- ifindex = nm_device_get_ip_ifindex(self);
- g_return_val_if_fail(ifindex > 0, NULL);
-
- platform = nm_device_get_platform(self);
-
- if (priv->ipv6ll_has) {
- dad6_add_pending_address(self, platform, ifindex, &priv->ipv6ll_addr, &dad6_config);
- }
-
- /* We are interested only in addresses that we have explicitly configured,
- * not in externally added ones.
- */
- for (i = 0; i < G_N_ELEMENTS(confs); i++) {
- if (!confs[i])
- continue;
-
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, confs[i], &addr) {
- dad6_add_pending_address(self, platform, ifindex, &addr->address, &dad6_config);
- }
- }
-
- return dad6_config;
-}
-
/*****************************************************************************/
static void
@@ -12151,21 +11517,6 @@ act_request_set(NMDevice *self, NMActRequest *act_request)
}
}
-static void
-dnsmasq_cleanup(NMDevice *self)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- if (!priv->dnsmasq_manager)
- return;
-
- nm_clear_g_signal_handler(priv->dnsmasq_manager, &priv->dnsmasq_state_id);
-
- nm_dnsmasq_manager_stop(priv->dnsmasq_manager);
- g_object_unref(priv->dnsmasq_manager);
- priv->dnsmasq_manager = NULL;
-}
-
gboolean
nm_device_is_nm_owned(NMDevice *self)
{
@@ -12257,26 +11608,14 @@ _cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type)
_set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_NONE);
- if (nm_clear_g_source(&priv->queued_ip_config_id_x[IS_IPv4])) {
- _LOGD(LOGD_DEVICE,
- "clearing queued IP%c config change",
- nm_utils_addr_family_to_char(addr_family));
- }
+ _dev_dhcpx_cleanup(self, addr_family, TRUE, FALSE);
if (IS_IPv4) {
- dhcp4_cleanup(self, cleanup_type, FALSE);
- arp_cleanup(self);
- dnsmasq_cleanup(self);
- ipv4ll_cleanup(self);
- g_slist_free_full(priv->acd.dad_list, (GDestroyNotify) nm_acd_manager_free);
- priv->acd.dad_list = NULL;
+ _dev_shared4_cleanup(self);
+ _dev_ll4_cleanup(self);
} else {
- g_slist_free_full(priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref);
- priv->dad6_failed_addrs = NULL;
- g_clear_object(&priv->dad6_ip6_config);
- dhcp6_cleanup(self, cleanup_type, FALSE);
nm_clear_g_source(&priv->linklocal6_timeout_id);
- addrconf6_cleanup(self);
+ _dev_ac6_cleanup(self);
}
}
@@ -12366,37 +11705,6 @@ nm_device_reactivate_ip_config(NMDevice * self,
if (priv->ip_state_x[IS_IPv4] == NM_DEVICE_IP_STATE_NONE)
return;
- g_clear_object(&priv->con_ip_config_x[IS_IPv4]);
- g_clear_object(&priv->ext_ip_config_x[IS_IPv4]);
- if (IS_IPv4) {
- g_clear_object(&priv->dev_ip_config_4.current);
- } else {
- g_clear_object(&priv->ac_ip6_config.current);
- g_clear_object(&priv->dhcp6.ip6_config.current);
- }
- g_clear_object(&priv->dev2_ip_config_x[IS_IPv4].current);
-
- if (!IS_IPv4) {
- if (priv->ipv6ll_handle && !IN6_IS_ADDR_UNSPECIFIED(&priv->ipv6ll_addr))
- priv->ipv6ll_has = TRUE;
- }
-
- priv->con_ip_config_x[IS_IPv4] = nm_device_ip_config_new(self, addr_family);
-
- if (IS_IPv4) {
- nm_ip4_config_merge_setting(priv->con_ip_config_4,
- s_ip_new,
- _prop_get_connection_mdns(self),
- _prop_get_connection_llmnr(self),
- nm_device_get_route_table(self, AF_INET),
- nm_device_get_route_metric(self, AF_INET));
- } else {
- nm_ip6_config_merge_setting(priv->con_ip_config_6,
- s_ip_new,
- nm_device_get_route_table(self, AF_INET6),
- nm_device_get_route_metric(self, AF_INET6));
- }
-
method_old = (s_ip_old ? nm_setting_ip_config_get_method(s_ip_old) : NULL)
?: (IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED
: NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
@@ -12415,58 +11723,7 @@ nm_device_reactivate_ip_config(NMDevice * self,
return;
}
- if (s_ip_old && s_ip_new) {
- gint64 metric_old, metric_new;
-
- /* For dynamic IP methods (DHCP, IPv4LL, WWAN) the route metric is
- * set at activation/renewal time using the value from static
- * configuration. To support runtime change we need to update the
- * dynamic configuration in place and tell the DHCP client the new
- * value to use for future renewals.
- */
- metric_old = nm_setting_ip_config_get_route_metric(s_ip_old);
- metric_new = nm_setting_ip_config_get_route_metric(s_ip_new);
-
- if (metric_old != metric_new) {
- if (IS_IPv4) {
- if (priv->dev_ip_config_4.orig) {
- nm_ip4_config_update_routes_metric((NMIP4Config *) priv->dev_ip_config_4.orig,
- nm_device_get_route_metric(self, AF_INET));
- }
- if (priv->dev2_ip_config_4.orig) {
- nm_ip4_config_update_routes_metric((NMIP4Config *) priv->dev2_ip_config_4.orig,
- nm_device_get_route_metric(self, AF_INET));
- }
- if (priv->dhcp_data_4.client) {
- nm_dhcp_client_set_route_metric(priv->dhcp_data_4.client,
- nm_device_get_route_metric(self, AF_INET));
- }
- } else {
- if (priv->ac_ip6_config.orig) {
- nm_ip6_config_update_routes_metric((NMIP6Config *) priv->ac_ip6_config.orig,
- nm_device_get_route_metric(self, AF_INET6));
- }
- if (priv->dhcp6.ip6_config.orig) {
- nm_ip6_config_update_routes_metric((NMIP6Config *) priv->dhcp6.ip6_config.orig,
- nm_device_get_route_metric(self, AF_INET6));
- }
- if (priv->dev2_ip_config_6.orig) {
- nm_ip6_config_update_routes_metric((NMIP6Config *) priv->dev2_ip_config_6.orig,
- nm_device_get_route_metric(self, AF_INET6));
- }
- if (priv->dhcp_data_6.client) {
- nm_dhcp_client_set_route_metric(priv->dhcp_data_6.client,
- nm_device_get_route_metric(self, AF_INET6));
- }
- }
- }
- }
-
- if (nm_device_get_ip_ifindex(self) > 0 && !ip_config_merge_and_apply(self, addr_family, TRUE)) {
- _LOGW(LOGD_IPX(IS_IPv4),
- "Failed to reapply IPv%c configuration",
- nm_utils_addr_family_to_char(addr_family));
- }
+ _dev_l3_cfg_commit(self, TRUE);
}
static void
@@ -12476,11 +11733,11 @@ _pacrunner_manager_add(NMDevice *self)
nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id);
- priv->pacrunner_conf_id = nm_pacrunner_manager_add(nm_pacrunner_manager_get(),
- priv->proxy_config,
- nm_device_get_ip_iface(self),
- NULL,
- NULL);
+ //XXX priv->pacrunner_conf_id = nm_pacrunner_manager_add(nm_pacrunner_manager_get(),
+ //XXX priv->proxy_config,
+ //XXX nm_device_get_ip_iface(self),
+ //XXX NULL,
+ //XXX NULL);
}
static void
@@ -12490,7 +11747,6 @@ reactivate_proxy_config(NMDevice *self)
if (!priv->pacrunner_conf_id)
return;
- nm_device_set_proxy_config(self, priv->dhcp4.pac_url);
_pacrunner_manager_add(self);
}
@@ -12711,6 +11967,7 @@ check_and_reapply_connection(NMDevice * self,
priv->v4_route_table_initialized = FALSE;
priv->v6_route_table_initialized = FALSE;
+ priv->l3config_merge_flags_has = FALSE;
/**************************************************************************
* Reapply changes
@@ -12970,96 +12227,6 @@ impl_device_get_applied_connection(NMDBusObject * obj,
/*****************************************************************************/
-typedef struct {
- gint64 timestamp_ms;
- bool dirty;
-} IP6RoutesTemporaryNotAvailableData;
-
-static gboolean
-_rt6_temporary_not_available_timeout(gpointer user_data)
-{
- NMDevice * self = NM_DEVICE(user_data);
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- priv->rt6_temporary_not_available_id = 0;
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-_rt6_temporary_not_available_set(NMDevice *self, GPtrArray *temporary_not_available)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- IP6RoutesTemporaryNotAvailableData *data;
- GHashTableIter iter;
- gint64 now_ms, oldest_ms;
- const gint64 MAX_AGE_MS = 20000;
- guint i;
- gboolean success = TRUE;
-
- if (!temporary_not_available || !temporary_not_available->len) {
- /* nothing outstanding. Clear tracking the routes. */
- nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref);
- nm_clear_g_source(&priv->rt6_temporary_not_available_id);
- return success;
- }
-
- if (priv->rt6_temporary_not_available) {
- g_hash_table_iter_init(&iter, priv->rt6_temporary_not_available);
- while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &data))
- data->dirty = TRUE;
- } else {
- priv->rt6_temporary_not_available =
- g_hash_table_new_full((GHashFunc) nmp_object_id_hash,
- (GEqualFunc) nmp_object_id_equal,
- (GDestroyNotify) nmp_object_unref,
- nm_g_slice_free_fcn(IP6RoutesTemporaryNotAvailableData));
- }
-
- now_ms = nm_utils_get_monotonic_timestamp_msec();
- oldest_ms = now_ms;
-
- for (i = 0; i < temporary_not_available->len; i++) {
- const NMPObject *o = temporary_not_available->pdata[i];
-
- data = g_hash_table_lookup(priv->rt6_temporary_not_available, o);
- if (data) {
- if (!data->dirty)
- continue;
- data->dirty = FALSE;
- nm_assert(data->timestamp_ms > 0 && data->timestamp_ms <= now_ms);
- if (now_ms > data->timestamp_ms + MAX_AGE_MS) {
- /* timeout. Could not add this address. */
- _LOGW(LOGD_DEVICE,
- "failure to add IPv6 route: %s",
- nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
- success = FALSE;
- } else
- oldest_ms = MIN(data->timestamp_ms, oldest_ms);
- continue;
- }
-
- data = g_slice_new0(IP6RoutesTemporaryNotAvailableData);
- data->timestamp_ms = now_ms;
- g_hash_table_insert(priv->rt6_temporary_not_available, (gpointer) nmp_object_ref(o), data);
- }
-
- g_hash_table_iter_init(&iter, priv->rt6_temporary_not_available);
- while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &data)) {
- if (data->dirty)
- g_hash_table_iter_remove(&iter);
- }
-
- nm_clear_g_source(&priv->rt6_temporary_not_available_id);
- priv->rt6_temporary_not_available_id =
- g_timeout_add(oldest_ms + MAX_AGE_MS - now_ms, _rt6_temporary_not_available_timeout, self);
-
- return success;
-}
-
-/*****************************************************************************/
-
static void
disconnect_cb(NMDevice * self,
GDBusMethodInvocation *context,
@@ -13442,315 +12609,53 @@ nm_device_is_activating(NMDevice *self)
return priv->activation_source_id_4 != 0;
}
-NMProxyConfig *
-nm_device_get_proxy_config(NMDevice *self)
-{
- g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
-
- return NM_DEVICE_GET_PRIVATE(self)->proxy_config;
-}
-
-static void
-nm_device_set_proxy_config(NMDevice *self, const char *pac_url)
-{
- NMDevicePrivate *priv;
- NMConnection * connection;
- NMSettingProxy * s_proxy = NULL;
-
- g_return_if_fail(NM_IS_DEVICE(self));
-
- priv = NM_DEVICE_GET_PRIVATE(self);
-
- g_clear_object(&priv->proxy_config);
- priv->proxy_config = nm_proxy_config_new();
-
- if (pac_url) {
- nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
- nm_proxy_config_set_pac_url(priv->proxy_config, pac_url);
- _LOGD(LOGD_PROXY, "proxy: PAC url \"%s\"", pac_url);
- } else
- nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
-
- connection = nm_device_get_applied_connection(self);
- if (connection)
- s_proxy = nm_connection_get_setting_proxy(connection);
-
- if (s_proxy)
- nm_proxy_config_merge_setting(priv->proxy_config, s_proxy);
-}
-
-/* IP Configuration stuff */
NMDhcpConfig *
nm_device_get_dhcp_config(NMDevice *self, int addr_family)
{
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
-
g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
- nm_assert_addr_family(addr_family);
-
- return NM_DEVICE_GET_PRIVATE(self)->dhcp_data_x[IS_IPv4].config;
+ return NM_DEVICE_GET_PRIVATE(self)->dhcp_data_x[NM_IS_IPv4(addr_family)].config;
}
-NMIP4Config *
-nm_device_get_ip4_config(NMDevice *self)
+const NML3Cfg *
+nm_device_get_l3cfg(NMDevice *self)
{
g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
- return NM_DEVICE_GET_PRIVATE(self)->ip_config_4;
-}
-
-static gboolean
-nm_device_set_ip_config(NMDevice * self,
- int addr_family,
- NMIPConfig *new_config,
- gboolean commit,
- GPtrArray * ip4_dev_route_blacklist)
-{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- NMIPConfig * old_config;
- gboolean has_changes = FALSE;
- gboolean success = TRUE;
- NMSettingsConnection * settings_connection;
- NMIPRouteTableSyncMode route_table_sync_mode;
-
- nm_assert_addr_family(addr_family);
- nm_assert(!new_config || nm_ip_config_get_addr_family(new_config) == addr_family);
- nm_assert(!new_config
- || (new_config && ({
- int ip_ifindex = nm_device_get_ip_ifindex(self);
-
- (ip_ifindex > 0 && ip_ifindex == nm_ip_config_get_ifindex(new_config));
- })));
- nm_assert(IS_IPv4 || !ip4_dev_route_blacklist);
-
- if (commit && new_config)
- route_table_sync_mode = _get_route_table_sync_mode_stateful(self, addr_family);
- else
- route_table_sync_mode = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE;
-
- _LOGD(LOGD_IPX(IS_IPv4),
- "ip%c-config: update (commit=%d, new-config=" NM_HASH_OBFUSCATE_PTR_FMT
- ", route-table-sync-mode=%d)",
- nm_utils_addr_family_to_char(addr_family),
- commit,
- NM_HASH_OBFUSCATE_PTR(new_config),
- (int) route_table_sync_mode);
-
- /* Always commit to nm-platform to update lifetimes */
- if (commit && new_config) {
- _commit_mtu(self, IS_IPv4 ? NM_IP4_CONFIG(new_config) : priv->ip_config_4);
-
- if (IS_IPv4) {
- success = nm_ip4_config_commit(NM_IP4_CONFIG(new_config),
- nm_device_get_platform(self),
- route_table_sync_mode);
- nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self),
- nm_ip_config_get_ifindex(new_config),
- ip4_dev_route_blacklist);
- } else {
- gs_unref_ptrarray GPtrArray *temporary_not_available = NULL;
-
- success = nm_ip6_config_commit(NM_IP6_CONFIG(new_config),
- nm_device_get_platform(self),
- route_table_sync_mode,
- &temporary_not_available);
-
- if (!_rt6_temporary_not_available_set(self, temporary_not_available))
- success = FALSE;
- }
- }
-
- old_config = priv->ip_config_x[IS_IPv4];
-
- if (new_config && old_config) {
- /* has_changes is set only on relevant changes, because when the configuration changes,
- * this causes a re-read and reset. This should only happen for relevant changes */
- nm_ip_config_replace(old_config, new_config, &has_changes);
- if (has_changes) {
- _LOGD(LOGD_IPX(IS_IPv4),
- "ip%c-config: update IP Config instance (%s)",
- nm_utils_addr_family_to_char(addr_family),
- nm_dbus_object_get_path(NM_DBUS_OBJECT(old_config)));
- }
- } else if (new_config /*&& !old_config*/) {
- has_changes = TRUE;
- priv->ip_config_x[IS_IPv4] = g_object_ref(new_config);
- if (!nm_dbus_object_is_exported(NM_DBUS_OBJECT(new_config)))
- nm_dbus_object_export(NM_DBUS_OBJECT(new_config));
-
- _LOGD(LOGD_IPX(IS_IPv4),
- "ip%c-config: set IP Config instance (%s)",
- nm_utils_addr_family_to_char(addr_family),
- nm_dbus_object_get_path(NM_DBUS_OBJECT(new_config)));
- } else if (old_config /*&& !new_config*/) {
- has_changes = TRUE;
- priv->ip_config_x[IS_IPv4] = NULL;
- _LOGD(LOGD_IPX(IS_IPv4),
- "ip%c-config: clear IP Config instance (%s)",
- nm_utils_addr_family_to_char(addr_family),
- nm_dbus_object_get_path(NM_DBUS_OBJECT(old_config)));
- if (IS_IPv4) {
- /* Device config is invalid if combined config is invalid */
- applied_config_clear(&priv->dev_ip_config_4);
- } else
- priv->needs_ip6_subnet = FALSE;
- }
-
- if (has_changes) {
- if (old_config != priv->ip_config_x[IS_IPv4])
- _notify(self, IS_IPv4 ? PROP_IP4_CONFIG : PROP_IP6_CONFIG);
-
- g_signal_emit(self,
- signals[IS_IPv4 ? IP4_CONFIG_CHANGED : IP6_CONFIG_CHANGED],
- 0,
- priv->ip_config_x[IS_IPv4],
- old_config);
-
- if (old_config != priv->ip_config_x[IS_IPv4])
- nm_dbus_object_clear_and_unexport(&old_config);
-
- if (nm_device_sys_iface_state_is_external(self)
- && (settings_connection = nm_device_get_settings_connection(self))
- && NM_FLAGS_HAS(nm_settings_connection_get_flags(settings_connection),
- NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL)
- && nm_active_connection_get_activation_type(NM_ACTIVE_CONNECTION(priv->act_request.obj))
- == NM_ACTIVATION_TYPE_EXTERNAL) {
- gs_unref_object NMConnection *new_connection = NULL;
-
- new_connection = nm_simple_connection_new_clone(
- nm_settings_connection_get_connection(settings_connection));
-
- nm_connection_add_setting(
- new_connection,
- IS_IPv4 ? nm_ip4_config_create_setting(priv->ip_config_4)
- : nm_ip6_config_create_setting(priv->ip_config_6,
- _get_maybe_ipv6_disabled(self)));
-
- nm_settings_connection_update(settings_connection,
- new_connection,
- NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY,
- NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
- NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
- NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET,
- "update-external",
- NULL);
- }
-
- nm_device_queue_recheck_assume(self);
-
- if (!IS_IPv4) {
- if (priv->ndisc)
- ndisc_set_router_config(priv->ndisc, self);
- }
- }
-
- nm_assert(!old_config || old_config == priv->ip_config_x[IS_IPv4]);
-
- return success;
-}
-
-static gboolean
-_replace_vpn_config_in_list(GSList **plist, GObject *old, GObject *new)
-{
- GSList *old_link;
-
- /* Below, assert that @new is not yet tracked, but still behave
- * correctly in any case. Don't complain for missing @old since
- * it could have been removed when the parent device became
- * unmanaged. */
-
- if (old && (old_link = g_slist_find(*plist, old))) {
- if (old != new) {
- if (new)
- old_link->data = g_object_ref(new);
- else
- *plist = g_slist_delete_link(*plist, old_link);
- g_object_unref(old);
- }
- return TRUE;
- }
-
- if (new) {
- if (!g_slist_find(*plist, new))
- *plist = g_slist_append(*plist, g_object_ref(new));
- else
- g_return_val_if_reached(TRUE);
- return TRUE;
- }
-
- return FALSE;
+ return NM_DEVICE_GET_PRIVATE(self)->l3cfg;
}
-void
-nm_device_replace_vpn4_config(NMDevice *self, NMIP4Config *old, NMIP4Config *config)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- nm_assert(!old || NM_IS_IP4_CONFIG(old));
- nm_assert(!config || NM_IS_IP4_CONFIG(config));
- nm_assert(!old || nm_ip4_config_get_ifindex(old) == nm_device_get_ip_ifindex(self));
- nm_assert(!config || nm_ip4_config_get_ifindex(config) == nm_device_get_ip_ifindex(self));
-
- if (!_replace_vpn_config_in_list(&priv->vpn_configs_4, (GObject *) old, (GObject *) config))
- return;
-
- /* NULL to use existing configs */
- if (!ip_config_merge_and_apply(self, AF_INET, TRUE))
- _LOGW(LOGD_IP4, "failed to set VPN routes for device");
-}
-
-void
-nm_device_set_dev2_ip_config(NMDevice *self, int addr_family, NMIPConfig *config)
+const NML3ConfigData *
+nm_device_get_l3cd(NMDevice *self, gboolean get_commited)
{
NMDevicePrivate *priv;
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- g_return_if_fail(NM_IS_DEVICE(self));
- g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6));
- g_return_if_fail(!config || nm_ip_config_get_addr_family(config) == addr_family);
+ g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
priv = NM_DEVICE_GET_PRIVATE(self);
- applied_config_init(&priv->dev2_ip_config_x[IS_IPv4], config);
- if (!ip_config_merge_and_apply(self, addr_family, TRUE)) {
- _LOGW(LOGD_IP,
- "failed to set extra device IPv%c configuration",
- nm_utils_addr_family_to_char(addr_family));
- }
-}
-
-void
-nm_device_replace_vpn6_config(NMDevice *self, NMIP6Config *old, NMIP6Config *config)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- nm_assert(!old || NM_IS_IP6_CONFIG(old));
- nm_assert(!config || NM_IS_IP6_CONFIG(config));
- nm_assert(!old || nm_ip6_config_get_ifindex(old) == nm_device_get_ip_ifindex(self));
- nm_assert(!config || nm_ip6_config_get_ifindex(config) == nm_device_get_ip_ifindex(self));
-
- if (!_replace_vpn_config_in_list(&priv->vpn_configs_6, (GObject *) old, (GObject *) config))
- return;
+ if (!priv->l3cfg)
+ return NULL;
- /* NULL to use existing configs */
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "failed to set VPN routes for device");
+ return nm_l3cfg_get_combined_l3cd(priv->l3cfg, get_commited);
}
-NMIP6Config *
-nm_device_get_ip6_config(NMDevice *self)
+void
+nm_device_set_dev2_ip_config(NMDevice *self, int addr_family, const NML3ConfigData *l3cd)
{
- g_return_val_if_fail(NM_IS_DEVICE(self), NULL);
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
- return NM_DEVICE_GET_PRIVATE(self)->ip_config_6;
+ _dev_l3_register_l3cds_set_one(self,
+ IS_IPv4 ? L3_CONFIG_DATA_TYPE_DEV_4 : L3_CONFIG_DATA_TYPE_DEV_6,
+ l3cd,
+ FALSE);
+ _dev_l3_cfg_commit(self, TRUE);
}
/*****************************************************************************/
static gboolean
-dispatcher_cleanup(NMDevice *self)
+_dispatcher_cleanup(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
@@ -13764,7 +12669,7 @@ dispatcher_cleanup(NMDevice *self)
}
static void
-dispatcher_complete_proceed_state(NMDispatcherCallId *call_id, gpointer user_data)
+_dispatcher_complete_proceed_state(NMDispatcherCallId *call_id, gpointer user_data)
{
NMDevice * self = NM_DEVICE(user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
@@ -13784,7 +12689,7 @@ ip_check_pre_up(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- if (dispatcher_cleanup(self))
+ if (_dispatcher_cleanup(self))
nm_assert_not_reached();
priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES;
@@ -13792,11 +12697,11 @@ ip_check_pre_up(NMDevice *self)
if (!nm_dispatcher_call_device(NM_DISPATCHER_ACTION_PRE_UP,
self,
NULL,
- dispatcher_complete_proceed_state,
+ _dispatcher_complete_proceed_state,
self,
&priv->dispatcher.call_id)) {
/* Just proceed on errors */
- dispatcher_complete_proceed_state(0, self);
+ _dispatcher_complete_proceed_state(0, self);
}
}
@@ -13988,17 +12893,21 @@ nm_device_start_ip_check(NMDevice *self)
buf[0] = '\0';
if (timeout) {
- const NMPObject *gw;
+ const NMPObject * gw;
+ const NML3ConfigData *l3cd;
- if (priv->ip_config_4 && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) {
- gw = nm_ip4_config_best_default_route_get(priv->ip_config_4);
+ l3cd = priv->l3cfg ? nm_l3cfg_get_combined_l3cd(priv->l3cfg, TRUE) : NULL;
+ if (!l3cd) {
+ /* pass */
+ } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) {
+ gw = nm_l3_config_data_get_best_default_route(l3cd, AF_INET);
if (gw) {
_nm_utils_inet4_ntop(NMP_OBJECT_CAST_IP4_ROUTE(gw)->gateway, buf);
ping_binary = nm_utils_find_helper("ping", "/usr/bin/ping", NULL);
log_domain = LOGD_IP4;
}
- } else if (priv->ip_config_6 && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) {
- gw = nm_ip6_config_best_default_route_get(priv->ip_config_6);
+ } else if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) {
+ gw = nm_l3_config_data_get_best_default_route(l3cd, AF_INET6);
if (gw) {
_nm_utils_inet6_ntop(&NMP_OBJECT_CAST_IP6_ROUTE(gw)->gateway, buf);
ping_binary = nm_utils_find_helper("ping6", "/usr/bin/ping6", NULL);
@@ -14137,15 +13046,7 @@ nm_device_bring_up(NMDevice *self, gboolean block, gboolean *no_firmware)
/* Can only get HW address of some devices when they are up */
nm_device_update_hw_address(self);
- /* when the link comes up, we must restore IP configuration if necessary. */
- if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) {
- if (!ip_config_merge_and_apply(self, AF_INET, TRUE))
- _LOGW(LOGD_IP4, "failed applying IP4 config after bringing link up");
- }
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) {
- if (!ip_config_merge_and_apply(self, AF_INET6, TRUE))
- _LOGW(LOGD_IP6, "failed applying IP6 config after bringing link up");
- }
+ _dev_l3_cfg_commit(self, TRUE);
return TRUE;
}
@@ -14208,381 +13109,6 @@ nm_device_get_firmware_missing(NMDevice *self)
return NM_DEVICE_GET_PRIVATE(self)->firmware_missing;
}
-static void
-intersect_ext_config(NMDevice * self,
- AppliedConfig *config,
- gboolean intersect_addresses,
- gboolean intersect_routes)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- NMIPConfig * ext;
- guint32 penalty;
- int family;
-
- if (!config->orig)
- return;
-
- family = nm_ip_config_get_addr_family(config->orig);
- penalty = default_route_metric_penalty_get(self, family);
- ext = family == AF_INET ? (NMIPConfig *) priv->ext_ip_config_4
- : (NMIPConfig *) priv->ext_ip_config_6;
-
- if (config->current) {
- nm_ip_config_intersect(config->current,
- ext,
- intersect_addresses,
- intersect_routes,
- penalty);
- } else {
- config->current = nm_ip_config_intersect_alloc(config->orig,
- ext,
- intersect_addresses,
- intersect_routes,
- penalty);
- }
-}
-
-static gboolean
-update_ext_ip_config(NMDevice *self, int addr_family, gboolean intersect_configs)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- int ifindex;
- GSList * iter;
- gboolean is_up;
-
- nm_assert_addr_family(addr_family);
-
- ifindex = nm_device_get_ip_ifindex(self);
- if (!ifindex)
- return FALSE;
-
- is_up = nm_platform_link_is_up(nm_device_get_platform(self), ifindex);
-
- if (NM_IS_IPv4(addr_family)) {
- g_clear_object(&priv->ext_ip_config_4);
- priv->ext_ip_config_4 = nm_ip4_config_capture(nm_device_get_multi_index(self),
- nm_device_get_platform(self),
- ifindex);
- if (priv->ext_ip_config_4) {
- if (intersect_configs) {
- /* This function was called upon external changes. Remove the configuration
- * (addresses,routes) that is no longer present externally from the internal
- * config. This way, we don't re-add addresses that were manually removed
- * by the user. */
- if (priv->con_ip_config_4) {
- nm_ip4_config_intersect(priv->con_ip_config_4,
- priv->ext_ip_config_4,
- TRUE,
- is_up,
- default_route_metric_penalty_get(self, AF_INET));
- }
-
- intersect_ext_config(self, &priv->dev_ip_config_4, TRUE, is_up);
- intersect_ext_config(self, &priv->dev2_ip_config_4, TRUE, is_up);
-
- for (iter = priv->vpn_configs_4; iter; iter = iter->next)
- nm_ip4_config_intersect(iter->data, priv->ext_ip_config_4, TRUE, is_up, 0);
- }
-
- /* Remove parts from ext_ip_config_4 to only contain the information that
- * was configured externally -- we already have the same configuration from
- * internal origins. */
- if (priv->con_ip_config_4) {
- nm_ip4_config_subtract(priv->ext_ip_config_4,
- priv->con_ip_config_4,
- default_route_metric_penalty_get(self, AF_INET));
- }
- if (applied_config_get_current(&priv->dev_ip_config_4)) {
- nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_4,
- applied_config_get_current(&priv->dev_ip_config_4),
- default_route_metric_penalty_get(self, AF_INET));
- }
- if (applied_config_get_current(&priv->dev2_ip_config_4)) {
- nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_4,
- applied_config_get_current(&priv->dev2_ip_config_4),
- default_route_metric_penalty_get(self, AF_INET));
- }
- for (iter = priv->vpn_configs_4; iter; iter = iter->next)
- nm_ip4_config_subtract(priv->ext_ip_config_4, iter->data, 0);
- }
-
- } else {
- nm_assert(!NM_IS_IPv4(addr_family));
-
- g_clear_object(&priv->ext_ip_config_6);
- g_clear_object(&priv->ext_ip6_config_captured);
- priv->ext_ip6_config_captured =
- nm_ip6_config_capture(nm_device_get_multi_index(self),
- nm_device_get_platform(self),
- ifindex,
- NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
- if (priv->ext_ip6_config_captured) {
- priv->ext_ip_config_6 = nm_ip6_config_new_cloned(priv->ext_ip6_config_captured);
-
- if (intersect_configs) {
- /* This function was called upon external changes. Remove the configuration
- * (addresses,routes) that is no longer present externally from the internal
- * config. This way, we don't re-add addresses that were manually removed
- * by the user. */
- if (priv->con_ip_config_6) {
- nm_ip6_config_intersect(priv->con_ip_config_6,
- priv->ext_ip_config_6,
- is_up,
- is_up,
- default_route_metric_penalty_get(self, AF_INET6));
- }
-
- intersect_ext_config(self, &priv->ac_ip6_config, is_up, is_up);
- intersect_ext_config(self, &priv->dhcp6.ip6_config, is_up, is_up);
- intersect_ext_config(self, &priv->dev2_ip_config_6, is_up, is_up);
-
- for (iter = priv->vpn_configs_6; iter; iter = iter->next)
- nm_ip6_config_intersect(iter->data, priv->ext_ip_config_6, is_up, is_up, 0);
-
- if (is_up && priv->ipv6ll_has
- && !nm_ip6_config_lookup_address(priv->ext_ip_config_6, &priv->ipv6ll_addr))
- priv->ipv6ll_has = FALSE;
- }
-
- /* Remove parts from ext_ip_config_6 to only contain the information that
- * was configured externally -- we already have the same configuration from
- * internal origins. */
- if (priv->con_ip_config_6) {
- nm_ip6_config_subtract(priv->ext_ip_config_6,
- priv->con_ip_config_6,
- default_route_metric_penalty_get(self, AF_INET6));
- }
- if (applied_config_get_current(&priv->ac_ip6_config)) {
- nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_6,
- applied_config_get_current(&priv->ac_ip6_config),
- default_route_metric_penalty_get(self, AF_INET6));
- }
- if (applied_config_get_current(&priv->dhcp6.ip6_config)) {
- nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_6,
- applied_config_get_current(&priv->dhcp6.ip6_config),
- default_route_metric_penalty_get(self, AF_INET6));
- }
- if (applied_config_get_current(&priv->dev2_ip_config_6)) {
- nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_6,
- applied_config_get_current(&priv->dev2_ip_config_6),
- default_route_metric_penalty_get(self, AF_INET6));
- }
- for (iter = priv->vpn_configs_6; iter; iter = iter->next)
- nm_ip6_config_subtract(priv->ext_ip_config_6, iter->data, 0);
- }
- }
-
- return TRUE;
-}
-
-static void
-update_ip_config(NMDevice *self, int addr_family)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- nm_assert_addr_family(addr_family);
-
- if (NM_IS_IPv4(addr_family))
- priv->update_ip_config_completed_v4 = TRUE;
- else
- priv->update_ip_config_completed_v6 = TRUE;
-
- if (update_ext_ip_config(self, addr_family, TRUE)) {
- if (NM_IS_IPv4(addr_family)) {
- if (priv->ext_ip_config_4)
- ip_config_merge_and_apply(self, AF_INET, FALSE);
- } else {
- if (priv->ext_ip6_config_captured)
- ip_config_merge_and_apply(self, AF_INET6, FALSE);
- }
- }
-}
-
-void
-nm_device_capture_initial_config(NMDevice *self)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
-
- if (!priv->update_ip_config_completed_v4)
- update_ip_config(self, AF_INET);
- if (!priv->update_ip_config_completed_v6)
- update_ip_config(self, AF_INET6);
-}
-
-static gboolean
-queued_ip_config_change(NMDevice *self, int addr_family)
-{
- NMDevicePrivate *priv;
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
-
- g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE);
-
- priv = NM_DEVICE_GET_PRIVATE(self);
-
- /* Wait for any queued state changes */
- if (priv->queued_state.id)
- return G_SOURCE_CONTINUE;
-
- /* If a commit is scheduled, this function would potentially interfere with
- * it changing IP configurations before they are applied. Postpone the
- * update in such case.
- */
- if (priv->activation_source_id_x[IS_IPv4] != 0
- && priv->activation_source_func_x[IS_IPv4]
- == activate_stage5_ip_config_result_x_fcn(addr_family))
- return G_SOURCE_CONTINUE;
-
- priv->queued_ip_config_id_x[IS_IPv4] = 0;
-
- update_ip_config(self, addr_family);
-
- if (!IS_IPv4) {
- /* Check whether we need to complete waiting for link-local.
- * We are also called from an idle handler, so no problem doing state transitions
- * now. */
- linklocal6_check_complete(self);
- }
-
- if (!IS_IPv4) {
- NMPlatform * platform;
- GSList * dad6_failed_addrs, *iter;
- const NMPlatformLink *pllink;
-
- dad6_failed_addrs = g_steal_pointer(&priv->dad6_failed_addrs);
-
- if (priv->state > NM_DEVICE_STATE_DISCONNECTED && priv->state < NM_DEVICE_STATE_DEACTIVATING
- && priv->ifindex > 0 && !nm_device_sys_iface_state_is_external(self)
- && (platform = nm_device_get_platform(self))
- && (pllink = nm_platform_link_get(platform, priv->ifindex))
- && (pllink->n_ifi_flags & IFF_UP)) {
- gboolean need_ipv6ll = FALSE;
- NMNDiscConfigMap ndisc_config_changed = NM_NDISC_CONFIG_NONE;
-
- /* Handle DAD failures */
- for (iter = dad6_failed_addrs; iter; iter = iter->next) {
- const NMPObject * obj = iter->data;
- const NMPlatformIP6Address *addr;
-
- if (!nm_ndisc_dad_addr_is_fail_candidate(platform, obj))
- continue;
-
- addr = NMP_OBJECT_CAST_IP6_ADDRESS(obj);
-
- _LOGI(LOGD_IP6,
- "ipv6: duplicate address check failed for the %s address",
- nm_platform_ip6_address_to_string(addr, NULL, 0));
-
- if (IN6_IS_ADDR_LINKLOCAL(&addr->address))
- need_ipv6ll = TRUE;
- else if (priv->ndisc)
- ndisc_config_changed |= nm_ndisc_dad_failed(priv->ndisc, &addr->address, FALSE);
- }
-
- if (ndisc_config_changed != NM_NDISC_CONFIG_NONE)
- nm_ndisc_emit_config_change(priv->ndisc, ndisc_config_changed);
-
- /* If no IPv6 link-local address exists but other addresses do then we
- * must add the LL address to remain conformant with RFC 3513 chapter 2.1
- * ("Addressing Model"): "All interfaces are required to have at least
- * one link-local unicast address".
- */
- if (priv->ip_config_6 && nm_ip6_config_get_num_addresses(priv->ip_config_6))
- need_ipv6ll = TRUE;
- if (need_ipv6ll)
- check_and_add_ipv6ll_addr(self);
- }
-
- g_slist_free_full(dad6_failed_addrs, (GDestroyNotify) nmp_object_unref);
- }
-
- if (!IS_IPv4) {
- /* Check if DAD is still pending */
- if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF && priv->dad6_ip6_config
- && priv->ext_ip6_config_captured
- && !nm_ip6_config_has_any_dad_pending(priv->ext_ip6_config_captured,
- priv->dad6_ip6_config)) {
- _LOGD(LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated");
- g_clear_object(&priv->dad6_ip6_config);
- _set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_DONE);
- check_ip_state(self, FALSE, TRUE);
- if (priv->rt6_temporary_not_available)
- nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL);
- }
- }
-
- set_unmanaged_external_down(self, TRUE);
-
- return G_SOURCE_REMOVE;
-}
-
-static gboolean
-queued_ip4_config_change(gpointer user_data)
-{
- return queued_ip_config_change(user_data, AF_INET);
-}
-
-static gboolean
-queued_ip6_config_change(gpointer user_data)
-{
- return queued_ip_config_change(user_data, AF_INET6);
-}
-
-static void
-device_ipx_changed(NMPlatform * platform,
- int obj_type_i,
- int ifindex,
- gconstpointer platform_object,
- int change_type_i,
- NMDevice * self)
-{
- const NMPObjectType obj_type = obj_type_i;
- const NMPlatformSignalChangeType change_type = change_type_i;
- NMDevicePrivate * priv;
- const NMPlatformIP6Address * addr;
-
- if (nm_device_get_ip_ifindex(self) != ifindex)
- return;
-
- if (!nm_device_is_real(self))
- return;
-
- if (nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)) {
- /* ignore all platform signals until the link is initialized in platform. */
- return;
- }
-
- priv = NM_DEVICE_GET_PRIVATE(self);
-
- switch (obj_type) {
- case NMP_OBJECT_TYPE_IP4_ADDRESS:
- case NMP_OBJECT_TYPE_IP4_ROUTE:
- if (!priv->queued_ip_config_id_4) {
- priv->queued_ip_config_id_4 = g_idle_add(queued_ip4_config_change, self);
- _LOGD(LOGD_DEVICE, "queued IP4 config change");
- }
- break;
- case NMP_OBJECT_TYPE_IP6_ADDRESS:
- addr = platform_object;
-
- if (priv->state > NM_DEVICE_STATE_DISCONNECTED && priv->state < NM_DEVICE_STATE_DEACTIVATING
- && nm_ndisc_dad_addr_is_fail_candidate_event(change_type, addr)) {
- priv->dad6_failed_addrs =
- g_slist_prepend(priv->dad6_failed_addrs,
- (gpointer) nmp_object_ref(NMP_OBJECT_UP_CAST(addr)));
- }
-
- /* fall-through */
- case NMP_OBJECT_TYPE_IP6_ROUTE:
- if (!priv->queued_ip_config_id_6) {
- priv->queued_ip_config_id_6 = g_idle_add(queued_ip6_config_change, self);
- _LOGD(LOGD_DEVICE, "queued IP6 config change");
- }
- break;
- default:
- g_return_if_reached();
- }
-}
-
/*****************************************************************************/
NM_UTILS_FLAGS2STR_DEFINE(nm_unmanaged_flags2str,
@@ -14835,12 +13361,6 @@ _set_unmanaged_flags(NMDevice * self,
nm_device_set_unmanaged_flags(self, NM_UNMANAGED_USER_SETTINGS, !!unmanaged);
}
- /* trigger an initial update of IP configuration. */
- nm_assert_se(!nm_clear_g_source(&priv->queued_ip_config_id_4));
- nm_assert_se(!nm_clear_g_source(&priv->queued_ip_config_id_6));
- priv->queued_ip_config_id_4 = g_idle_add(queued_ip4_config_change, self);
- priv->queued_ip_config_id_6 = g_idle_add(queued_ip6_config_change, self);
-
if (!priv->pending_actions) {
do_notify_has_pending_actions = TRUE;
had_pending_actions = nm_device_has_pending_action(self);
@@ -15192,9 +13712,13 @@ nm_device_update_metered(NMDevice *self)
/* Try to guess a value using the metered flag in IP configuration */
if (value == NM_METERED_INVALID) {
- if (priv->ip_config_4 && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE
- && nm_ip4_config_get_metered(priv->ip_config_4))
- value = NM_METERED_GUESS_YES;
+ if (priv->l3cfg) {
+ const NML3ConfigData *l3cd;
+
+ l3cd = nm_l3cfg_get_combined_l3cd(priv->l3cfg, TRUE);
+ if (l3cd && nm_l3_config_data_get_metered(l3cd))
+ value = NM_METERED_GUESS_YES;
+ }
}
/* Otherwise, look at connection type. For Bluetooth, we look at the type of
@@ -15762,7 +14286,7 @@ _cancel_activation(NMDevice *self)
priv->fw_state = FIREWALL_STATE_INITIALIZED;
}
- dispatcher_cleanup(self);
+ _dispatcher_cleanup(self);
ip_check_gw_ping_cleanup(self);
/* Break the activation chain */
@@ -15797,7 +14321,7 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type)
queued_state_clear(self);
- nm_clear_pointer(&priv->shared_ip_handle, nm_netns_shared_ip_release);
+ _dev_shared4_cleanup(self);
for (i = 0; i < 2; i++)
nm_clear_pointer(&priv->hostname_resolver_x[i], _hostname_resolver_free);
@@ -15816,6 +14340,7 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type)
priv->v4_route_table_initialized = FALSE;
priv->v6_route_table_initialized = FALSE;
+ priv->l3config_merge_flags_has = FALSE;
priv->v4_route_table_all_sync_before = FALSE;
priv->v6_route_table_all_sync_before = FALSE;
@@ -15825,39 +14350,12 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type)
priv->linklocal6_dad_counter = 0;
- priv->mtu_force_set_done = FALSE;
-
- /* Clean up IP configs; this does not actually deconfigure the
- * interface; the caller must flush routes and addresses explicitly.
- */
- nm_device_set_ip_config(self, AF_INET, NULL, TRUE, NULL);
- nm_device_set_ip_config(self, AF_INET6, NULL, TRUE, NULL);
- g_clear_object(&priv->proxy_config);
- g_clear_object(&priv->con_ip_config_4);
- applied_config_clear(&priv->dev_ip_config_4);
- applied_config_clear(&priv->dev2_ip_config_4);
- g_clear_object(&priv->ext_ip_config_4);
- g_clear_object(&priv->ip_config_4);
- g_clear_object(&priv->con_ip_config_6);
- applied_config_clear(&priv->ac_ip6_config);
- g_clear_object(&priv->ext_ip_config_6);
- g_clear_object(&priv->ext_ip6_config_captured);
- applied_config_clear(&priv->dev2_ip_config_6);
- g_clear_object(&priv->ip_config_6);
- g_clear_object(&priv->dad6_ip6_config);
- priv->ipv6ll_has = FALSE;
- memset(&priv->ipv6ll_addr, 0, sizeof(priv->ipv6ll_addr));
+ priv->ipv6ll_has = FALSE;
+ priv->ipv6ll_addr = nm_ip_addr_zero.addr6;
- nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref);
- nm_clear_g_source(&priv->rt6_temporary_not_available_id);
-
- g_slist_free_full(priv->vpn_configs_4, g_object_unref);
- priv->vpn_configs_4 = NULL;
- g_slist_free_full(priv->vpn_configs_6, g_object_unref);
- priv->vpn_configs_6 = NULL;
+ priv->mtu_force_set_done = FALSE;
- /* We no longer accept the delegations. nm_device_set_ip_config(NULL)
- * above disables them. */
+ /* We no longer accept the delegations and don't expect the value to be set. */
nm_assert(priv->needs_ip6_subnet == FALSE);
if (priv->act_request.obj) {
@@ -16027,18 +14525,19 @@ deactivate_reset_hw_addr(NMDevice *self)
static char *
find_dhcp4_address(NMDevice *self)
{
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
- const NMPlatformIP4Address *a;
- NMDedupMultiIter ipconf_iter;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ const NMPObject *obj;
- if (!priv->ip_config_4)
+ if (!priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_4].d)
return NULL;
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, priv->ip_config_4, &a) {
- if (a->addr_source == NM_IP_CONFIG_SOURCE_DHCP)
- return nm_utils_inet4_ntop_dup(a->address);
- }
- return NULL;
+ obj = nm_l3_config_data_get_first_obj(priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_4].d,
+ NMP_OBJECT_TYPE_IP4_ADDRESS,
+ NULL);
+ if (!obj)
+ return NULL;
+
+ return nm_utils_inet4_ntop_dup(NMP_OBJECT_CAST_IP4_ADDRESS(obj)->address);
}
void
@@ -16050,7 +14549,6 @@ nm_device_spawn_iface_helper(NMDevice *self)
GError * error = NULL;
const char * method;
GPtrArray * argv;
- gs_free char * dhcp4_address = NULL;
char * logging_backend;
NMUtilsStableType stable_type;
const char * stable_id;
@@ -16095,10 +14593,9 @@ nm_device_spawn_iface_helper(NMDevice *self)
g_ptr_array_add(argv, g_strdup("--log-domains"));
g_ptr_array_add(argv, g_strdup(nm_logging_domains_to_string()));
- dhcp4_address = find_dhcp4_address(self);
-
method = nm_device_get_effective_ip_config_method(self, AF_INET);
if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
+ char * dhcp4_address;
NMSettingIPConfig *s_ip4;
s_ip4 = nm_connection_get_setting_ip4_config(connection);
@@ -16107,8 +14604,12 @@ nm_device_spawn_iface_helper(NMDevice *self)
g_ptr_array_add(argv, g_strdup("--priority4"));
g_ptr_array_add(argv, g_strdup_printf("%u", nm_device_get_route_metric(self, AF_INET)));
- g_ptr_array_add(argv, g_strdup("--dhcp4"));
- g_ptr_array_add(argv, g_strdup(dhcp4_address));
+ dhcp4_address = find_dhcp4_address(self);
+ if (dhcp4_address) {
+ g_ptr_array_add(argv, g_strdup("--dhcp4"));
+ g_ptr_array_add(argv, dhcp4_address);
+ }
+
if (nm_setting_ip_config_get_may_fail(s_ip4) == FALSE)
g_ptr_array_add(argv, g_strdup("--dhcp4-required"));
@@ -16158,7 +14659,7 @@ nm_device_spawn_iface_helper(NMDevice *self)
g_ptr_array_add(argv, g_strdup("--slaac-required"));
g_ptr_array_add(argv, g_strdup("--slaac-tempaddr"));
- g_ptr_array_add(argv, g_strdup_printf("%d", priv->ndisc_use_tempaddr));
+ g_ptr_array_add(argv, g_strdup_printf("%d", (int) priv->ac6_ip6_privacy));
if (nm_device_get_ip_iface_identifier(self, &iid, FALSE)) {
g_ptr_array_add(argv, g_strdup("--iid"));
@@ -16209,23 +14710,6 @@ nm_device_spawn_iface_helper(NMDevice *self)
/*****************************************************************************/
-static gboolean
-ip_config_valid(NMDeviceState state)
-{
- return (state == NM_DEVICE_STATE_UNMANAGED)
- || (state >= NM_DEVICE_STATE_IP_CHECK && state <= NM_DEVICE_STATE_DEACTIVATING);
-}
-
-static void
-notify_ip_properties(NMDevice *self)
-{
- _notify(self, PROP_IP_IFACE);
- _notify(self, PROP_IP4_CONFIG);
- _notify(self, PROP_DHCP4_CONFIG);
- _notify(self, PROP_IP6_CONFIG);
- _notify(self, PROP_DHCP6_CONFIG);
-}
-
static void
ip6_managed_setup(NMDevice *self)
{
@@ -16364,9 +14848,9 @@ deactivate_dispatcher_complete(NMDispatcherCallId *call_id, gpointer user_data)
static void
_set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting)
{
- NMDevicePrivate *priv;
- NMDeviceState old_state;
- gs_unref_object NMActRequest *req = NULL;
+ gs_unref_object NMActRequest *req = NULL;
+ NMDevicePrivate * priv;
+ NMDeviceState old_state;
gboolean no_firmware = FALSE;
NMSettingsConnection * sett_conn;
NMSettingSriov * s_sriov;
@@ -16376,8 +14860,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
priv = NM_DEVICE_GET_PRIVATE(self);
- /* Track re-entry */
- g_warn_if_fail(priv->in_state_changed == FALSE);
+ g_return_if_fail(priv->in_state_changed == 0);
old_state = priv->state;
@@ -16414,14 +14897,14 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
* by the device not having any pending action anymore
* we add one here that gets removed at the end of the function */
nm_device_add_pending_action(self, NM_PENDING_ACTION_IN_STATE_CHANGE, TRUE);
- priv->in_state_changed = TRUE;
+ priv->in_state_changed++;
priv->state = state;
priv->state_reason = reason;
queued_state_clear(self);
- dispatcher_cleanup(self);
+ _dispatcher_cleanup(self);
nm_clear_g_cancellable(&priv->deactivating_cancellable);
@@ -16628,9 +15111,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
_LOGI(LOGD_DEVICE, "Activation: successful, device activated.");
nm_device_update_metered(self);
nm_dispatcher_call_device(NM_DISPATCHER_ACTION_UP, self, req, NULL, NULL, NULL);
-
- if (priv->proxy_config)
- _pacrunner_manager_add(self);
+ _pacrunner_manager_add(self);
break;
case NM_DEVICE_STATE_FAILED:
/* Usually upon failure the activation chain is interrupted in
@@ -16690,11 +15171,6 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
fw_change_zone(self);
} else
nm_device_start_ip_check(self);
-
- /* IP-related properties are only valid when the device has IP configuration;
- * now that it does, ensure their change notifications are emitted.
- */
- notify_ip_properties(self);
break;
}
case NM_DEVICE_STATE_SECONDARIES:
@@ -16717,18 +15193,13 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
}
}
- /* IP-related properties are only valid when the device has IP configuration.
- * If it no longer does, ensure their change notifications are emitted.
- */
- if (ip_config_valid(old_state) && !ip_config_valid(state))
- notify_ip_properties(self);
-
concheck_now = NM_IN_SET(state, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_DISCONNECTED)
|| old_state >= NM_DEVICE_STATE_ACTIVATED;
concheck_update_interval(self, AF_INET, concheck_now);
concheck_update_interval(self, AF_INET6, concheck_now);
- priv->in_state_changed = FALSE;
+ priv->in_state_changed--;
+
nm_device_remove_pending_action(self, NM_PENDING_ACTION_IN_STATE_CHANGE, TRUE);
if ((old_state > NM_DEVICE_STATE_UNMANAGED) != (state > NM_DEVICE_STATE_UNMANAGED))
@@ -17790,14 +16261,14 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean
* whether it changed from the previous lookup */
ip_config = priv->ip_config_x[IS_IPv4];
if (ip_config) {
- const NMPlatformIPAddress *addr;
+ //XXX const NMPlatformIPAddress *addr;
- addr = nm_ip_config_get_first_address(ip_config);
- if (addr) {
- new_address = g_inet_address_new_from_bytes(addr->address_ptr,
- IS_IPv4 ? G_SOCKET_FAMILY_IPV4
- : G_SOCKET_FAMILY_IPV6);
- }
+ //XXX addr = nm_ip_config_get_first_address(ip_config);
+ //XXX if (addr) {
+ //XXX new_address = g_inet_address_new_from_bytes(addr->address_ptr,
+ //XXX IS_IPv4 ? G_SOCKET_FAMILY_IPV4
+ //XXX : G_SOCKET_FAMILY_IPV6);
+ //XXX }
}
if (new_address && resolver->address) {
@@ -17912,13 +16383,10 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
nm_utils_str_utf8safe_escape_cp(priv->iface, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL));
break;
case PROP_IP_IFACE:
- if (ip_config_valid(priv->state)) {
- g_value_take_string(
- value,
- nm_utils_str_utf8safe_escape_cp(nm_device_get_ip_iface(self),
- NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL));
- } else
- g_value_set_string(value, NULL);
+ g_value_take_string(
+ value,
+ nm_utils_str_utf8safe_escape_cp(nm_device_get_ip_iface(self),
+ NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL));
break;
case PROP_IFINDEX:
g_value_set_int(value, priv->ifindex);
@@ -17953,24 +16421,16 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
g_value_set_uint(value, priv->mtu);
break;
case PROP_IP4_CONFIG:
- nm_dbus_utils_g_value_set_object_path(value,
- ip_config_valid(priv->state) ? priv->ip_config_4
- : NULL);
+ nm_dbus_utils_g_value_set_object_path(value, priv->ip_config_4);
break;
case PROP_DHCP4_CONFIG:
- nm_dbus_utils_g_value_set_object_path(
- value,
- ip_config_valid(priv->state) ? priv->dhcp_data_4.config : NULL);
+ nm_dbus_utils_g_value_set_object_path(value, priv->dhcp_data_4.config);
break;
case PROP_IP6_CONFIG:
- nm_dbus_utils_g_value_set_object_path(value,
- ip_config_valid(priv->state) ? priv->ip_config_6
- : NULL);
+ nm_dbus_utils_g_value_set_object_path(value, priv->ip_config_6);
break;
case PROP_DHCP6_CONFIG:
- nm_dbus_utils_g_value_set_object_path(
- value,
- ip_config_valid(priv->state) ? priv->dhcp_data_6.config : NULL);
+ nm_dbus_utils_g_value_set_object_path(value, priv->dhcp_data_6.config);
break;
case PROP_STATE:
g_value_set_uint(value, priv->state);
@@ -18281,24 +16741,7 @@ constructed(GObject *object)
if (NM_DEVICE_GET_CLASS(self)->get_generic_capabilities)
priv->capabilities |= NM_DEVICE_GET_CLASS(self)->get_generic_capabilities(self);
- /* Watch for external IP config changes */
platform = nm_device_get_platform(self);
- g_signal_connect(platform,
- NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED,
- G_CALLBACK(device_ipx_changed),
- self);
- g_signal_connect(platform,
- NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
- G_CALLBACK(device_ipx_changed),
- self);
- g_signal_connect(platform,
- NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED,
- G_CALLBACK(device_ipx_changed),
- self);
- g_signal_connect(platform,
- NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
- G_CALLBACK(device_ipx_changed),
- self);
g_signal_connect(platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK(link_changed_cb), self);
priv->manager = g_object_ref(NM_MANAGER_GET);
@@ -18350,15 +16793,12 @@ dispose(GObject *object)
_parent_set_ifindex(self, 0, FALSE);
platform = nm_device_get_platform(self);
- g_signal_handlers_disconnect_by_func(platform, G_CALLBACK(device_ipx_changed), self);
g_signal_handlers_disconnect_by_func(platform, G_CALLBACK(link_changed_cb), self);
- arp_cleanup(self);
-
nm_clear_g_signal_handler(nm_config_get(), &priv->config_changed_id);
nm_clear_g_signal_handler(priv->manager, &priv->ifindex_changed_id);
- dispatcher_cleanup(self);
+ _dispatcher_cleanup(self);
nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id);
@@ -18436,7 +16876,6 @@ finalize(GObject *object)
g_free(priv->hw_addr_perm);
g_free(priv->hw_addr_initial);
g_slist_free(priv->pending_actions);
- g_slist_free_full(priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref);
nm_clear_g_free(&priv->physical_port_id);
g_free(priv->udi);
g_free(priv->path);
@@ -18951,29 +17390,17 @@ nm_device_class_init(NMDeviceClass *klass)
G_TYPE_BOOLEAN,
0);
- signals[IP4_CONFIG_CHANGED] = g_signal_new(NM_DEVICE_IP4_CONFIG_CHANGED,
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 2,
- G_TYPE_OBJECT,
- G_TYPE_OBJECT);
-
- signals[IP6_CONFIG_CHANGED] = g_signal_new(NM_DEVICE_IP6_CONFIG_CHANGED,
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 2,
- G_TYPE_OBJECT,
- G_TYPE_OBJECT);
+ signals[L3CD_CHANGED] = g_signal_new(NM_DEVICE_L3CD_CHANGED,
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER, /* (const NML3ConfigData *l3cd_old) */
+ G_TYPE_POINTER /* (const NML3ConfigData *l3cd_new) */);
signals[IP6_PREFIX_DELEGATED] = g_signal_new(NM_DEVICE_IP6_PREFIX_DELEGATED,
G_OBJECT_CLASS_TYPE(object_class),
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
index 53211c6f2f..90bcb48ff5 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -70,8 +70,7 @@
/* Internal signals */
#define NM_DEVICE_DNS_LOOKUP_DONE "dns-lookup-done"
-#define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed"
-#define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed"
+#define NM_DEVICE_L3CD_CHANGED "l3cd-changed"
#define NM_DEVICE_IP6_PREFIX_DELEGATED "ip6-prefix-delegated"
#define NM_DEVICE_IP6_SUBNET_NEEDED "ip6-subnet-needed"
#define NM_DEVICE_REMOVED "removed"
@@ -343,15 +342,16 @@ typedef struct _NMDeviceClass {
NMActStageReturn (*act_stage1_prepare)(NMDevice *self, NMDeviceStateReason *out_failure_reason);
NMActStageReturn (*act_stage2_config)(NMDevice *self, NMDeviceStateReason *out_failure_reason);
- NMActStageReturn (*act_stage3_ip_config_start)(NMDevice * self,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason);
+ NMActStageReturn (*act_stage3_ip_config_start)(NMDevice * self,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason);
NMActStageReturn (*act_stage4_ip_config_timeout)(NMDevice * self,
int addr_family,
NMDeviceStateReason *out_failure_reason);
- void (*ip4_config_pre_commit)(NMDevice *self, NMIP4Config *config);
+ //XXX: needs rework to not use NMIP4Config.
+ void (*ip4_config_pre_commit)(NMDevice *self);
/* Async deactivating (in the DEACTIVATING phase) */
void (*deactivate_async)(NMDevice * self,
@@ -459,16 +459,11 @@ const char *nm_device_get_permanent_hw_address_full(NMDevice *self,
gboolean *out_is_fake);
const char *nm_device_get_initial_hw_address(NMDevice *dev);
-NMProxyConfig *nm_device_get_proxy_config(NMDevice *dev);
-
NMDhcpConfig *nm_device_get_dhcp_config(NMDevice *dev, int addr_family);
-NMIP4Config * nm_device_get_ip4_config(NMDevice *dev);
-void nm_device_replace_vpn4_config(NMDevice *dev, NMIP4Config *old, NMIP4Config *config);
-NMIP6Config *nm_device_get_ip6_config(NMDevice *dev);
-void nm_device_replace_vpn6_config(NMDevice *dev, NMIP6Config *old, NMIP6Config *config);
+const NML3Cfg *nm_device_get_l3cfg(NMDevice *self);
-void nm_device_capture_initial_config(NMDevice *dev);
+const NML3ConfigData *nm_device_get_l3cd(NMDevice *self, gboolean get_commited);
int nm_device_parent_get_ifindex(NMDevice *dev);
NMDevice *nm_device_parent_get_device(NMDevice *dev);
diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c
index 26a5ba002c..f18102cfe2 100644
--- a/src/core/devices/ovs/nm-device-ovs-bridge.c
+++ b/src/core/devices/ovs/nm-device-ovs-bridge.c
@@ -67,10 +67,10 @@ get_generic_capabilities(NMDevice *device)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
return NM_ACT_STAGE_RETURN_IP_FAIL;
}
diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c
index 46a612aca7..ad04e9fea7 100644
--- a/src/core/devices/ovs/nm-device-ovs-interface.c
+++ b/src/core/devices/ovs/nm-device-ovs-interface.c
@@ -189,10 +189,10 @@ set_platform_mtu(NMDevice *device, guint32 mtu)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device);
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(device);
@@ -212,7 +212,7 @@ act_stage3_ip_config_start(NMDevice * device,
}
return NM_DEVICE_CLASS(nm_device_ovs_interface_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static gboolean
diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c
index f11c585235..be1a51be8d 100644
--- a/src/core/devices/ovs/nm-device-ovs-port.c
+++ b/src/core/devices/ovs/nm-device-ovs-port.c
@@ -60,10 +60,10 @@ get_generic_capabilities(NMDevice *device)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
return NM_ACT_STAGE_RETURN_IP_FAIL;
}
diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c
index 0f1a8c4cec..5fa16790d0 100644
--- a/src/core/devices/team/nm-device-team.c
+++ b/src/core/devices/team/nm-device-team.c
@@ -22,7 +22,6 @@
#include "nm-config.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-dbus-manager.h"
-#include "nm-ip4-config.h"
#include "libnm-std-aux/nm-dbus-compat.h"
#define _NMLOG_DEVICE_TYPE NMDeviceTeam
diff --git a/src/core/devices/tests/meson.build b/src/core/devices/tests/meson.build
index 1bc883706e..871c320629 100644
--- a/src/core/devices/tests/meson.build
+++ b/src/core/devices/tests/meson.build
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
test_units = [
- 'test-acd',
'test-lldp',
]
diff --git a/src/core/devices/tests/test-acd.c b/src/core/devices/tests/test-acd.c
deleted file mode 100644
index b4b6516549..0000000000
--- a/src/core/devices/tests/test-acd.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2015 Red Hat, Inc.
- */
-
-#include "src/core/nm-default-daemon.h"
-
-#include "n-acd/src/n-acd.h"
-
-#include <linux/if_ether.h>
-
-#include "devices/nm-acd-manager.h"
-#include "platform/tests/test-common.h"
-
-#define IFACE_VETH0 "nm-test-veth0"
-#define IFACE_VETH1 "nm-test-veth1"
-
-#define ADDR1 0x01010101
-#define ADDR2 0x02020202
-#define ADDR3 0x03030303
-#define ADDR4 0x04040404
-
-/*****************************************************************************/
-
-static gboolean
-_skip_acd_test_check(void)
-{
- NAcd * acd;
- NAcdConfig * config;
- const guint8 hwaddr[ETH_ALEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
- int r;
- static int skip = -1;
-
- if (skip == -1) {
- r = n_acd_config_new(&config);
- g_assert(r == 0);
-
- n_acd_config_set_ifindex(config, 1);
- n_acd_config_set_transport(config, N_ACD_TRANSPORT_ETHERNET);
- n_acd_config_set_mac(config, hwaddr, sizeof(hwaddr));
-
- r = n_acd_new(&acd, config);
- n_acd_config_free(config);
- if (r == 0)
- n_acd_unref(acd);
-
- skip = (r != 0);
- }
- return skip;
-}
-
-#define _skip_acd_test() \
- ({ \
- gboolean _skip = _skip_acd_test_check(); \
- \
- if (_skip) \
- g_test_skip("Cannot create NAcd. Running under valgind?"); \
- _skip; \
- })
-
-/*****************************************************************************/
-
-typedef struct {
- int ifindex0;
- int ifindex1;
- const guint8 *hwaddr0;
- const guint8 *hwaddr1;
- size_t hwaddr0_len;
- size_t hwaddr1_len;
-} test_fixture;
-
-static void
-fixture_setup(test_fixture *fixture, gconstpointer user_data)
-{
- /* create veth pair. */
- fixture->ifindex0 =
- nmtstp_link_veth_add(NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex;
- fixture->ifindex1 =
- nmtstp_link_get_typed(NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex;
-
- g_assert(nm_platform_link_change_flags(NM_PLATFORM_GET, fixture->ifindex0, IFF_UP, TRUE) >= 0);
- g_assert(nm_platform_link_change_flags(NM_PLATFORM_GET, fixture->ifindex1, IFF_UP, TRUE) >= 0);
-
- fixture->hwaddr0 =
- nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex0, &fixture->hwaddr0_len);
- fixture->hwaddr1 =
- nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex1, &fixture->hwaddr1_len);
-}
-
-typedef struct {
- in_addr_t addresses[8];
- in_addr_t peer_addresses[8];
- gboolean expected_result[8];
-} TestInfo;
-
-static void
-acd_manager_probe_terminated(NMAcdManager *acd_manager, gpointer user_data)
-{
- g_main_loop_quit(user_data);
-}
-
-static void
-test_acd_common(test_fixture *fixture, TestInfo *info)
-{
- nm_auto_free_acdmgr NMAcdManager *manager = NULL;
- nm_auto_unref_gmainloop GMainLoop *loop = NULL;
- int i;
- const guint WAIT_TIME_OPTIMISTIC = 50;
- guint wait_time;
- static const NMAcdCallbacks callbacks = {
- .probe_terminated_callback = acd_manager_probe_terminated,
- .user_data_destroy = (GDestroyNotify) g_main_loop_unref,
- };
- int r;
-
- if (_skip_acd_test())
- return;
-
- /* first, try with a short waittime. We hope that this is long enough
- * to successfully complete the test. Only if that's not the case, we
- * assume the computer is currently busy (high load) and we retry with
- * a longer timeout. */
- wait_time = WAIT_TIME_OPTIMISTIC;
-again:
-
- nm_clear_pointer(&loop, g_main_loop_unref);
- loop = g_main_loop_new(NULL, FALSE);
-
- nm_clear_pointer(&manager, nm_acd_manager_free);
- manager = nm_acd_manager_new(fixture->ifindex0,
- fixture->hwaddr0,
- fixture->hwaddr0_len,
- &callbacks,
- g_main_loop_ref(loop));
- g_assert(manager != NULL);
-
- for (i = 0; info->addresses[i]; i++)
- g_assert(nm_acd_manager_add_address(manager, info->addresses[i]));
-
- for (i = 0; info->peer_addresses[i]; i++) {
- nmtstp_ip4_address_add(NULL,
- FALSE,
- fixture->ifindex1,
- info->peer_addresses[i],
- 24,
- 0,
- 3600,
- 1800,
- 0,
- NULL);
- }
-
- r = nm_acd_manager_start_probe(manager, wait_time);
- g_assert_cmpint(r, ==, 0);
-
- g_assert(nmtst_main_loop_run(loop, 2000));
-
- for (i = 0; info->addresses[i]; i++) {
- gboolean val;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
-
- val = nm_acd_manager_check_address(manager, info->addresses[i]);
- if (val == info->expected_result[i])
- continue;
-
- if (wait_time == WAIT_TIME_OPTIMISTIC) {
- /* probably we just had a glitch and the system took longer than
- * expected. Re-verify with a large timeout this time. */
- wait_time = 1000;
- goto again;
- }
-
- g_error("expected check for address #%d (%s) to %s, but it didn't",
- i,
- _nm_utils_inet4_ntop(info->addresses[i], sbuf),
- info->expected_result[i] ? "detect no duplicated" : "detect a duplicate");
- }
-}
-
-static void
-test_acd_probe_1(test_fixture *fixture, gconstpointer user_data)
-{
- TestInfo info = {.addresses = {ADDR1, ADDR2, ADDR3},
- .peer_addresses = {ADDR4},
- .expected_result = {TRUE, TRUE, TRUE}};
-
- test_acd_common(fixture, &info);
-}
-
-static void
-test_acd_probe_2(test_fixture *fixture, gconstpointer user_data)
-{
- TestInfo info = {.addresses = {ADDR1, ADDR2, ADDR3, ADDR4},
- .peer_addresses = {ADDR3, ADDR2},
- .expected_result = {TRUE, FALSE, FALSE, TRUE}};
-
- test_acd_common(fixture, &info);
-}
-
-static void
-test_acd_announce(test_fixture *fixture, gconstpointer user_data)
-{
- nm_auto_free_acdmgr NMAcdManager *manager = NULL;
- nm_auto_unref_gmainloop GMainLoop *loop = NULL;
- int r;
-
- if (_skip_acd_test())
- return;
-
- manager =
- nm_acd_manager_new(fixture->ifindex0, fixture->hwaddr0, fixture->hwaddr0_len, NULL, NULL);
- g_assert(manager != NULL);
-
- g_assert(nm_acd_manager_add_address(manager, ADDR1));
- g_assert(nm_acd_manager_add_address(manager, ADDR2));
-
- loop = g_main_loop_new(NULL, FALSE);
- r = nm_acd_manager_announce_addresses(manager);
- g_assert_cmpint(r, ==, 0);
- g_assert(!nmtst_main_loop_run(loop, 200));
-}
-
-static void
-fixture_teardown(test_fixture *fixture, gconstpointer user_data)
-{
- nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex0);
- nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex1);
-}
-
-NMTstpSetupFunc const _nmtstp_setup_platform_func = nm_linux_platform_setup;
-
-void
-_nmtstp_init_tests(int *argc, char ***argv)
-{
- nmtst_init_with_logging(argc, argv, NULL, "ALL");
-}
-
-void
-_nmtstp_setup_tests(void)
-{
- g_test_add("/acd/probe/1",
- test_fixture,
- NULL,
- fixture_setup,
- test_acd_probe_1,
- fixture_teardown);
- g_test_add("/acd/probe/2",
- test_fixture,
- NULL,
- fixture_setup,
- test_acd_probe_2,
- fixture_teardown);
- g_test_add("/acd/announce",
- test_fixture,
- NULL,
- fixture_setup,
- test_acd_announce,
- fixture_teardown);
-}
diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c
index a8ea2ed7e5..92c6f96269 100644
--- a/src/core/devices/wifi/nm-device-wifi-p2p.c
+++ b/src/core/devices/wifi/nm-device-wifi-p2p.c
@@ -17,7 +17,6 @@
#include "nm-act-request.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-glib-aux/nm-ref-string.h"
-#include "nm-ip4-config.h"
#include "nm-manager.h"
#include "nm-manager.h"
#include "nm-setting-wifi-p2p.h"
@@ -555,10 +554,10 @@ remove_all_peers(NMDeviceWifiP2P *self)
/*****************************************************************************/
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
gboolean indicate_addressing_running;
NMConnection *connection;
@@ -582,7 +581,7 @@ act_stage3_ip_config_start(NMDevice * device,
TRUE);
return NM_DEVICE_CLASS(nm_device_wifi_p2p_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static void
diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c
index dd52186d82..af7b2a2160 100644
--- a/src/core/devices/wifi/nm-device-wifi.c
+++ b/src/core/devices/wifi/nm-device-wifi.c
@@ -31,7 +31,6 @@
#include "nm-setting-wireless-security.h"
#include "nm-setting-8021x.h"
#include "nm-setting-ip4-config.h"
-#include "nm-ip4-config.h"
#include "nm-setting-ip6-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-auth-utils.h"
@@ -3271,10 +3270,10 @@ out_fail:
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
gboolean indicate_addressing_running;
NMConnection *connection;
@@ -3297,7 +3296,7 @@ act_stage3_ip_config_start(NMDevice * device,
TRUE);
return NM_DEVICE_CLASS(nm_device_wifi_parent_class)
- ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason);
+ ->act_stage3_ip_config_start(device, addr_family, out_l3cd, out_failure_reason);
}
static guint32
diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c
index a8d2a161fc..3d49026006 100644
--- a/src/core/devices/wwan/nm-device-modem.c
+++ b/src/core/devices/wwan/nm-device-modem.c
@@ -8,7 +8,7 @@
#include "nm-device-modem.h"
#include "nm-modem.h"
-#include "nm-ip4-config.h"
+#include "nm-l3-config-data.h"
#include "devices/nm-device-private.h"
#include "nm-rfkill-manager.h"
#include "settings/nm-settings-connection.h"
@@ -33,6 +33,7 @@ typedef struct {
NMModem * modem;
NMDeviceModemCapabilities caps;
NMDeviceModemCapabilities current_caps;
+ NMUtilsIPv6IfaceId iid;
char * device_id;
char * operator_code;
char * apn;
@@ -188,35 +189,36 @@ modem_auth_result(NMModem *modem, GError *error, gpointer user_data)
}
static void
-modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data)
-{
- NMDeviceModem *self = NM_DEVICE_MODEM(user_data);
- NMDevice * device = NM_DEVICE(self);
+modem_new_config(NMModem * modem,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ gboolean do_slaac,
+ const NMUtilsIPv6IfaceId *iid,
+ GError * error,
+ gpointer user_data)
+{
+ NMDeviceModem * self = NM_DEVICE_MODEM(user_data);
+ NMDeviceModemPrivate * priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
+ NMDevice * device = NM_DEVICE(self);
+ NMActStageReturn ret;
+ NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_ignored = NULL;
- g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE);
+ if (addr_family == AF_INET) {
+ g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE);
- if (error) {
- _LOGW(LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message);
- nm_device_ip_method_failed(device, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
- } else {
- nm_device_set_dev2_ip_config(device, AF_INET, NM_IP_CONFIG_CAST(config));
- nm_device_activate_schedule_ip_config_result(device, AF_INET, NULL);
- }
-}
+ if (error) {
+ _LOGW(LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message);
+ nm_device_ip_method_failed(device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ return;
+ }
-static void
-modem_ip6_config_result(NMModem * modem,
- NMIP6Config *config,
- gboolean do_slaac,
- GError * error,
- gpointer user_data)
-{
- NMDeviceModem * self = NM_DEVICE_MODEM(user_data);
- NMDevice * device = NM_DEVICE(self);
- NMActStageReturn ret;
- NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
- gs_unref_object NMIP6Config *ignored = NULL;
- gboolean got_config = !!config;
+ nm_device_set_dev2_ip_config(device, AF_INET, l3cd);
+ nm_device_activate_schedule_ip_config_result(device, AF_INET);
+ return;
+ }
g_return_if_fail(nm_device_activate_ip6_state_in_conf(device) == TRUE);
@@ -226,15 +228,19 @@ modem_ip6_config_result(NMModem * modem,
return;
}
+ if (iid)
+ priv->iid = *iid;
+ else
+ priv->iid.id = 0;
+
/* Re-enable IPv6 on the interface */
nm_device_sysctl_ip_conf_set(device, AF_INET6, "disable_ipv6", "0");
- if (config)
- nm_device_set_dev2_ip_config(device, AF_INET6, NM_IP_CONFIG_CAST(config));
+ nm_device_set_dev2_ip_config(device, AF_INET6, l3cd);
if (do_slaac == FALSE) {
- if (got_config)
- nm_device_activate_schedule_ip_config_result(device, AF_INET6, NULL);
+ if (l3cd)
+ nm_device_activate_schedule_ip_config_result(device, AF_INET6);
else {
_LOGW(LOGD_MB | LOGD_IP6,
"retrieving IPv6 configuration failed: SLAAC not requested and no addresses");
@@ -246,11 +252,10 @@ modem_ip6_config_result(NMModem * modem,
}
/* Start SLAAC now that we have a link-local address from the modem */
- ret =
- NM_DEVICE_CLASS(nm_device_modem_parent_class)
- ->act_stage3_ip_config_start(device, AF_INET6, (gpointer *) &ignored, &failure_reason);
+ ret = NM_DEVICE_CLASS(nm_device_modem_parent_class)
+ ->act_stage3_ip_config_start(device, AF_INET6, &l3cd_ignored, &failure_reason);
- nm_assert(ignored == NULL);
+ nm_assert(!l3cd_ignored);
switch (ret) {
case NM_ACT_STAGE_RETURN_FAILURE:
@@ -258,7 +263,7 @@ modem_ip6_config_result(NMModem * modem,
break;
case NM_ACT_STAGE_RETURN_IP_FAIL:
/* all done */
- nm_device_activate_schedule_ip_config_result(device, AF_INET6, NULL);
+ nm_device_activate_schedule_ip_config_result(device, AF_INET6);
break;
case NM_ACT_STAGE_RETURN_POSTPONE:
/* let SLAAC run */
@@ -602,10 +607,10 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
static NMActStageReturn
-act_stage3_ip_config_start(NMDevice * device,
- int addr_family,
- gpointer * out_config,
- NMDeviceStateReason *out_failure_reason)
+act_stage3_ip_config_start(NMDevice * device,
+ int addr_family,
+ const NML3ConfigData **out_l3cd,
+ NMDeviceStateReason * out_failure_reason)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
@@ -622,9 +627,9 @@ act_stage3_ip_config_start(NMDevice * device,
}
static void
-ip4_config_pre_commit(NMDevice *device, NMIP4Config *config)
+ip4_config_pre_commit(NMDevice *device)
{
- nm_modem_ip4_pre_commit(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem, device, config);
+ nm_modem_ip4_pre_commit(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem, device);
}
static gboolean
@@ -632,14 +637,15 @@ get_ip_iface_identifier(NMDevice *device, NMUtilsIPv6IfaceId *out_iid)
{
NMDeviceModem * self = NM_DEVICE_MODEM(device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
- gboolean success;
g_return_val_if_fail(priv->modem, FALSE);
- success = nm_modem_get_iid(priv->modem, out_iid);
- if (!success)
- success =
- NM_DEVICE_CLASS(nm_device_modem_parent_class)->get_ip_iface_identifier(device, out_iid);
- return success;
+
+ if (priv->iid.id != 0) {
+ *out_iid = priv->iid;
+ return TRUE;
+ }
+
+ return NM_DEVICE_CLASS(nm_device_modem_parent_class)->get_ip_iface_identifier(device, out_iid);
}
/*****************************************************************************/
@@ -705,8 +711,7 @@ set_modem(NMDeviceModem *self, NMModem *modem)
g_signal_connect(modem, NM_MODEM_PPP_FAILED, G_CALLBACK(ppp_failed), self);
g_signal_connect(modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK(modem_prepare_result), self);
- g_signal_connect(modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK(modem_ip4_config_result), self);
- g_signal_connect(modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK(modem_ip6_config_result), self);
+ g_signal_connect(modem, NM_MODEM_NEW_CONFIG, G_CALLBACK(modem_new_config), self);
g_signal_connect(modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK(modem_auth_requested), self);
g_signal_connect(modem, NM_MODEM_AUTH_RESULT, G_CALLBACK(modem_auth_result), self);
g_signal_connect(modem, NM_MODEM_STATE_CHANGED, G_CALLBACK(modem_state_cb), self);
diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c
index 0872a8a1f9..8535909625 100644
--- a/src/core/devices/wwan/nm-modem-broadband.c
+++ b/src/core/devices/wwan/nm-modem-broadband.c
@@ -15,8 +15,7 @@
#include "NetworkManagerUtils.h"
#include "devices/nm-device-private.h"
#include "libnm-platform/nm-platform.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
+#include "nm-l3-config-data.h"
#define NM_MODEM_BROADBAND_MODEM "modem"
@@ -964,21 +963,23 @@ set_mm_enabled(NMModem *_self, gboolean enabled)
/* IPv4 method static */
static gboolean
-static_stage3_ip4_done(NMModemBroadband *self)
+static_stage3_ip4_done(gpointer user_data)
{
- GError * error = NULL;
- gs_unref_object NMIP4Config *config = NULL;
- const char * data_port;
- const char * address_string;
- const char * gw_string;
- guint32 address_network;
- guint32 gw = 0;
- NMPlatformIP4Address address;
- const char ** dns;
- guint i;
- guint32 ip4_route_table, ip4_route_metric;
- NMPlatformIP4Route * r;
- guint32 mtu_n;
+ NMModemBroadband * self = user_data;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ char sbuf[sizeof(_nm_utils_to_string_buffer)];
+ gs_free_error GError *error = NULL;
+ const char * data_port;
+ const char * address_string;
+ const char * gw_string;
+ guint32 address_network;
+ guint32 gw = 0;
+ NMPlatformIP4Address address;
+ const char ** dns;
+ int ifindex;
+ guint i;
+ NMPlatformIP4Route route;
+ guint32 mtu_n;
g_return_val_if_fail(self->_priv.ipv4_config, FALSE);
g_return_val_if_fail(self->_priv.bearer, FALSE);
@@ -991,58 +992,72 @@ static_stage3_ip4_done(NMModemBroadband *self)
address_string = mm_bearer_ip_config_get_address(self->_priv.ipv4_config);
if (!address_string
|| !nm_utils_parse_inaddr_bin(AF_INET, address_string, NULL, &address_network)) {
- error =
- g_error_new(NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IP4 configuration failed: invalid address given %s%s%s",
- nm_modem_get_uid(NM_MODEM(self)),
- NM_PRINT_FMT_QUOTE_STRING(address_string));
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IP4 configuration failed: invalid address given %s%s%s",
+ nm_modem_get_uid(NM_MODEM(self)),
+ NM_PRINT_FMT_QUOTE_STRING(address_string));
goto out;
}
/* Missing gateway not a hard failure */
gw_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv4_config);
if (gw_string && !nm_utils_parse_inaddr_bin(AF_INET, gw_string, NULL, &gw)) {
- error =
- g_error_new(NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IP4 configuration failed: invalid gateway address \"%s\"",
- nm_modem_get_uid(NM_MODEM(self)),
- gw_string);
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IP4 configuration failed: invalid gateway address \"%s\"",
+ nm_modem_get_uid(NM_MODEM(self)),
+ gw_string);
goto out;
}
data_port = mm_bearer_get_interface(self->_priv.bearer);
g_return_val_if_fail(data_port, FALSE);
- config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
- nm_platform_link_get_ifindex(NM_PLATFORM_GET, data_port));
-
- memset(&address, 0, sizeof(address));
- address.address = address_network;
- address.peer_address = address_network;
- address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv4_config);
- address.addr_source = NM_IP_CONFIG_SOURCE_WWAN;
+
+ ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, data_port);
+ if (ifindex <= 0) {
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) data port %s not found",
+ nm_modem_get_uid(NM_MODEM(self)),
+ data_port);
+ goto out;
+ }
+
+ l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex);
+
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_WWAN);
+
+ address = (NMPlatformIP4Address){
+ .address = address_network,
+ .peer_address = address_network,
+ .plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv4_config),
+ .addr_source = NM_IP_CONFIG_SOURCE_WWAN,
+ };
if (address.plen <= 32)
- nm_ip4_config_add_address(config, &address);
+ nm_l3_config_data_add_address_4(l3cd, &address);
- _LOGI(" address %s/%d", address_string, address.plen);
+ _LOGI(" address %s", nm_platform_ip4_address_to_string(&address, sbuf, sizeof(sbuf)));
- nm_modem_get_route_parameters(NM_MODEM(self), &ip4_route_table, &ip4_route_metric, NULL, NULL);
- r = &(NMPlatformIP4Route){
+ route = (NMPlatformIP4Route){
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
.gateway = gw,
- .table_coerced = nm_platform_route_table_coerce(ip4_route_table),
- .metric = ip4_route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
- nm_ip4_config_add_route(config, r, NULL);
+ nm_l3_config_data_add_route_4(l3cd, &route);
_LOGI(" gateway %s", gw_string);
- /* DNS servers */
dns = mm_bearer_ip_config_get_dns(self->_priv.ipv4_config);
for (i = 0; dns && dns[i]; i++) {
if (nm_utils_parse_inaddr_bin(AF_INET, dns[i], NULL, &address_network)
&& address_network > 0) {
- nm_ip4_config_add_nameserver(config, address_network);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET, &address_network);
_LOGI(" DNS %s", dns[i]);
}
}
@@ -1050,15 +1065,17 @@ static_stage3_ip4_done(NMModemBroadband *self)
#if MM_CHECK_VERSION(1, 4, 0)
mtu_n = mm_bearer_ip_config_get_mtu(self->_priv.ipv4_config);
if (mtu_n) {
- nm_ip4_config_set_mtu(config, mtu_n, NM_IP_CONFIG_SOURCE_WWAN);
+ nm_l3_config_data_set_mtu(l3cd, mtu_n);
_LOGI(" MTU %u", mtu_n);
}
#endif
out:
- g_signal_emit_by_name(self, NM_MODEM_IP4_CONFIG_RESULT, config, error);
- g_clear_error(&error);
- return FALSE;
+ if (error)
+ nm_clear_l3cd(&l3cd);
+
+ nm_modem_emit_signal_new_config(NM_MODEM(self), AF_INET, l3cd, FALSE, NULL, error);
+ return G_SOURCE_REMOVE;
}
static NMActStageReturn
@@ -1072,8 +1089,7 @@ static_stage3_ip4_config_start(NMModem * modem,
/* We schedule it in an idle just to follow the same logic as in the
* generic modem implementation. */
nm_clear_g_source(&priv->idle_id_ip4);
- priv->idle_id_ip4 = g_idle_add((GSourceFunc) static_stage3_ip4_done, self);
-
+ priv->idle_id_ip4 = g_idle_add(static_stage3_ip4_done, self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -1081,21 +1097,26 @@ static_stage3_ip4_config_start(NMModem * modem,
/* IPv6 method static */
static gboolean
-stage3_ip6_done(NMModemBroadband *self)
+stage3_ip6_done(gpointer user_data)
{
- GError * error = NULL;
- NMIP6Config * config = NULL;
- const char * data_port;
- const char * address_string;
- NMPlatformIP6Address address;
- NMModemIPMethod ip_method;
- const char ** dns;
- guint i;
-
- g_return_val_if_fail(self->_priv.ipv6_config, FALSE);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ char sbuf[sizeof(_nm_utils_to_string_buffer)];
+ NMModemBroadband * self = user_data;
+ gs_free_error GError * error = NULL;
+ const char * data_port;
+ const char * address_string;
+ NMPlatformIP6Address address;
+ NMModemIPMethod ip_method;
+ const char ** dns;
+ guint i;
+ gboolean do_slaac = TRUE;
+ int ifindex;
+ NMUtilsIPv6IfaceId iid_data;
+ const NMUtilsIPv6IfaceId *iid = NULL;
+
+ g_return_val_if_fail(self->_priv.ipv6_config, G_SOURCE_REMOVE);
self->_priv.idle_id_ip6 = 0;
- memset(&address, 0, sizeof(address));
ip_method = get_bearer_ip_method(self->_priv.ipv6_config);
@@ -1103,93 +1124,112 @@ stage3_ip6_done(NMModemBroadband *self)
if (!address_string) {
/* DHCP/SLAAC is allowed to skip addresses; other methods require it */
if (ip_method != NM_MODEM_IP_METHOD_AUTO) {
- error = g_error_new(NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IPv6 configuration failed: no address given",
- nm_modem_get_uid(NM_MODEM(self)));
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IPv6 configuration failed: no address given",
+ nm_modem_get_uid(NM_MODEM(self)));
}
goto out;
}
- /* Fail if invalid IP address retrieved */
- if (!inet_pton(AF_INET6, address_string, (void *) &(address.address))) {
- error = g_error_new(NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IPv6 configuration failed: invalid address given '%s'",
- nm_modem_get_uid(NM_MODEM(self)),
- address_string);
+ address = (NMPlatformIP6Address){};
+
+ if (!inet_pton(AF_INET6, address_string, &address.address)) {
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IPv6 configuration failed: invalid address given '%s'",
+ nm_modem_get_uid(NM_MODEM(self)),
+ address_string);
goto out;
}
- _LOGI("IPv6 base configuration:");
-
data_port = mm_bearer_get_interface(self->_priv.bearer);
- g_return_val_if_fail(data_port, FALSE);
+ g_return_val_if_fail(data_port, G_SOURCE_REMOVE);
+
+ ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, data_port);
+ if (ifindex <= 0) {
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) data port %s not found",
+ nm_modem_get_uid(NM_MODEM(self)),
+ data_port);
+ goto out;
+ }
+
+ _LOGI("IPv6 base configuration:");
- config = nm_ip6_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
- nm_platform_link_get_ifindex(NM_PLATFORM_GET, data_port));
+ l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex);
address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config);
- if (address.plen <= 128)
- nm_ip6_config_add_address(config, &address);
+ if (address.plen <= 128) {
+ if (IN6_IS_ADDR_LINKLOCAL(&address.address)) {
+ iid_data.id = ((guint64 *) (&address.address.s6_addr))[1];
+ iid = &iid_data;
+ } else
+ do_slaac = FALSE;
+ nm_l3_config_data_add_address_6(l3cd, &address);
+ }
- _LOGI(" address %s/%d", address_string, address.plen);
+ _LOGI(" address %s (slaac %s)",
+ nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf)),
+ do_slaac ? "enabled" : "disabled");
address_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config);
if (address_string) {
- guint32 ip6_route_table, ip6_route_metric;
-
if (inet_pton(AF_INET6, address_string, &address.address) != 1) {
- error =
- g_error_new(NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'",
- nm_modem_get_uid(NM_MODEM(self)),
- address_string);
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'",
+ nm_modem_get_uid(NM_MODEM(self)),
+ address_string);
goto out;
}
- nm_modem_get_route_parameters(NM_MODEM(self),
- NULL,
- NULL,
- &ip6_route_table,
- &ip6_route_metric);
{
const NMPlatformIP6Route r = {
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
.gateway = address.address,
- .table_coerced = nm_platform_route_table_coerce(ip6_route_table),
- .metric = ip6_route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
_LOGI(" gateway %s", address_string);
- nm_ip6_config_add_route(config, &r, NULL);
+ nm_l3_config_data_add_route_6(l3cd, &r);
}
} else if (ip_method == NM_MODEM_IP_METHOD_STATIC) {
/* Gateway required for the 'static' method */
- error = g_error_new(NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IPv6 configuration failed: missing gateway",
- nm_modem_get_uid(NM_MODEM(self)));
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IPv6 configuration failed: missing gateway",
+ nm_modem_get_uid(NM_MODEM(self)));
goto out;
}
- /* DNS servers */
dns = mm_bearer_ip_config_get_dns(self->_priv.ipv6_config);
for (i = 0; dns && dns[i]; i++) {
struct in6_addr addr;
if (inet_pton(AF_INET6, dns[i], &addr)) {
- nm_ip6_config_add_nameserver(config, &addr);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET6, &addr);
_LOGI(" DNS %s", dns[i]);
}
}
out:
- nm_modem_emit_ip6_config_result(NM_MODEM(self), config, error);
- g_clear_object(&config);
- g_clear_error(&error);
- return FALSE;
+ if (error) {
+ nm_clear_l3cd(&l3cd);
+ do_slaac = FALSE;
+ iid = NULL;
+ }
+ nm_modem_emit_signal_new_config(NM_MODEM(self), AF_INET6, l3cd, do_slaac, iid, error);
+ return G_SOURCE_REMOVE;
}
static NMActStageReturn
@@ -1201,7 +1241,7 @@ stage3_ip6_config_request(NMModem *modem, NMDeviceStateReason *out_failure_reaso
/* We schedule it in an idle just to follow the same logic as in the
* generic modem implementation. */
nm_clear_g_source(&priv->idle_id_ip6);
- priv->idle_id_ip6 = g_idle_add((GSourceFunc) stage3_ip6_done, self);
+ priv->idle_id_ip6 = g_idle_add(stage3_ip6_done, self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c
index 78ad7b6820..d31325d1f1 100644
--- a/src/core/devices/wwan/nm-modem-ofono.c
+++ b/src/core/devices/wwan/nm-modem-ofono.c
@@ -11,7 +11,7 @@
#include "devices/nm-device-private.h"
#include "nm-modem.h"
#include "libnm-platform/nm-platform.h"
-#include "nm-ip4-config.h"
+#include "nm-l3-config-data.h"
#define VARIANT_IS_OF_TYPE_BOOLEAN(v) \
((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_BOOLEAN)))
@@ -47,7 +47,7 @@ typedef struct {
gboolean modem_online;
gboolean gprs_attached;
- NMIP4Config *ip4_config;
+ NML3ConfigData *l3cd_4;
} NMModemOfonoPrivate;
struct _NMModemOfono {
@@ -240,7 +240,7 @@ deactivate_cleanup(NMModem *modem, NMDevice *device, gboolean stop_ppp_manager)
/* TODO: cancel SimpleConnect() if any */
- g_clear_object(&priv->ip4_config);
+ nm_clear_l3cd(&priv->l3cd_4);
NM_MODEM_CLASS(nm_modem_ofono_parent_class)
->deactivate_cleanup(modem, device, stop_ppp_manager);
@@ -734,13 +734,13 @@ handle_settings(GVariant *v_dict, gpointer user_data)
{
NMModemOfono * self = NM_MODEM_OFONO(user_data);
NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
- NMPlatformIP4Address addr;
+ char sbuf[sizeof(_nm_utils_to_string_buffer)];
+ NMPlatformIP4Address address;
gboolean ret = FALSE;
const char * interface;
const char * s;
- const char ** array, **iter;
+ const char ** array;
guint32 address_network, gateway_network;
- guint32 ip4_route_table, ip4_route_metric;
int ifindex;
GError * error = NULL;
@@ -773,12 +773,13 @@ handle_settings(GVariant *v_dict, gpointer user_data)
}
ifindex = nm_modem_get_ip_ifindex(NM_MODEM(self));
- nm_assert(ifindex > 0);
+ g_return_if_fail(ifindex > 0);
- /* TODO: verify handling of ip4_config; check other places it's used... */
- g_clear_object(&priv->ip4_config);
+ /* TODO: verify handling of l3cd_4; check other places it's used... */
+ nm_clear_l3cd(&priv->l3cd_4);
- priv->ip4_config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex);
+ priv->l3cd_4 = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex);
+ nm_l3_config_data_set_source(priv->l3cd_4, NM_IP_CONFIG_SOURCE_WWAN);
if (!g_variant_lookup(v_dict, "Address", "&s", &s)) {
_LOGW("Settings 'Address' missing");
@@ -788,10 +789,12 @@ handle_settings(GVariant *v_dict, gpointer user_data)
_LOGW("can't convert 'Address' %s to addr", s ?: "");
goto out;
}
- memset(&addr, 0, sizeof(addr));
- addr.ifindex = ifindex;
- addr.address = address_network;
- addr.addr_source = NM_IP_CONFIG_SOURCE_WWAN;
+
+ address = (NMPlatformIP4Address){
+ .ifindex = ifindex,
+ .address = address_network,
+ .addr_source = NM_IP_CONFIG_SOURCE_WWAN,
+ };
if (!g_variant_lookup(v_dict, "Netmask", "&s", &s)) {
_LOGW("Settings 'Netmask' missing");
@@ -801,10 +804,10 @@ handle_settings(GVariant *v_dict, gpointer user_data)
_LOGW("invalid 'Netmask': %s", s ?: "");
goto out;
}
- addr.plen = nm_utils_ip4_netmask_to_prefix(address_network);
+ address.plen = nm_utils_ip4_netmask_to_prefix(address_network);
- _LOGI("Address: %s", nm_platform_ip4_address_to_string(&addr, NULL, 0));
- nm_ip4_config_add_address(priv->ip4_config, &addr);
+ _LOGI("Address: %s", nm_platform_ip4_address_to_string(&address, sbuf, sizeof(sbuf)));
+ nm_l3_config_data_add_address_4(priv->l3cd_4, &address);
if (!g_variant_lookup(v_dict, "Gateway", "&s", &s) || !s) {
_LOGW("Settings 'Gateway' missing");
@@ -814,17 +817,18 @@ handle_settings(GVariant *v_dict, gpointer user_data)
_LOGW("invalid 'Gateway': %s", s);
goto out;
}
- nm_modem_get_route_parameters(NM_MODEM(self), &ip4_route_table, &ip4_route_metric, NULL, NULL);
{
const NMPlatformIP4Route r = {
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
.gateway = gateway_network,
- .table_coerced = nm_platform_route_table_coerce(ip4_route_table),
- .metric = ip4_route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
_LOGI("Gateway: %s", s);
- nm_ip4_config_add_route(priv->ip4_config, &r, NULL);
+ nm_l3_config_data_add_route_4(priv->l3cd_4, &r);
}
if (!g_variant_lookup(v_dict, "DomainNameServers", "^a&s", &array)) {
@@ -832,52 +836,49 @@ handle_settings(GVariant *v_dict, gpointer user_data)
goto out;
}
if (array) {
- for (iter = array; *iter; iter++) {
- if (nm_utils_parse_inaddr_bin(AF_INET, *iter, NULL, &address_network)
- && address_network) {
- _LOGI("DNS: %s", *iter);
- nm_ip4_config_add_nameserver(priv->ip4_config, address_network);
- } else {
- _LOGW("invalid NameServer: %s", *iter);
+ gs_free const char **array_free = array;
+ gboolean any_good = FALSE;
+
+ for (; array[0]; array++) {
+ if (!nm_utils_parse_inaddr_bin(AF_INET, *array, NULL, &address_network)
+ || !address_network) {
+ _LOGW("invalid NameServer: %s", *array);
+ continue;
}
+ any_good = TRUE;
+ _LOGI("DNS: %s", *array);
+ nm_l3_config_data_add_nameserver(priv->l3cd_4, AF_INET, &address_network);
}
-
- if (iter == array) {
+ if (!any_good) {
_LOGW("Settings: 'DomainNameServers': none specified");
- g_free(array);
goto out;
}
- g_free(array);
}
if (g_variant_lookup(v_dict, "MessageProxy", "&s", &s)) {
_LOGI("MessageProxy: %s", s);
if (s && nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) {
- nm_modem_get_route_parameters(NM_MODEM(self),
- &ip4_route_table,
- &ip4_route_metric,
- NULL,
- NULL);
-
- {
- const NMPlatformIP4Route mms_route = {
- .network = address_network,
- .plen = 32,
- .gateway = gateway_network,
- .table_coerced = nm_platform_route_table_coerce(ip4_route_table),
- .metric = ip4_route_metric,
- };
-
- nm_ip4_config_add_route(priv->ip4_config, &mms_route, NULL);
- }
- } else {
+ const NMPlatformIP4Route mms_route = {
+ .network = address_network,
+ .plen = 32,
+ .gateway = gateway_network,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
+ };
+
+ nm_l3_config_data_add_route_4(priv->l3cd_4, &mms_route);
+ } else
_LOGW("invalid MessageProxy: %s", s);
- }
}
ret = TRUE;
out:
+ if (priv->l3cd_4)
+ nm_l3_config_data_seal(priv->l3cd_4);
+
if (nm_modem_get_state(NM_MODEM(self)) != NM_MODEM_STATE_CONNECTED) {
_LOGI("emitting PREPARE_RESULT: %s", ret ? "TRUE" : "FALSE");
nm_modem_emit_prepare_result(NM_MODEM(self),
@@ -917,20 +918,19 @@ static_stage3_ip4_config_start(NMModem * modem,
NMActRequest * req,
NMDeviceStateReason *out_failure_reason)
{
- NMModemOfono * self = NM_MODEM_OFONO(modem);
- NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
- GError * error = NULL;
+ NMModemOfono * self = NM_MODEM_OFONO(modem);
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
- if (!priv->ip4_config) {
+ if (!priv->l3cd_4) {
_LOGD("IP4 config not ready(?)");
return NM_ACT_STAGE_RETURN_FAILURE;
}
_LOGD("IP4 config is done; setting modem_state -> CONNECTED");
- g_signal_emit_by_name(self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error);
- /* Signal listener takes ownership of the IP4Config */
- priv->ip4_config = NULL;
+ nm_modem_emit_signal_new_config(NM_MODEM(self), AF_INET, priv->l3cd_4, FALSE, NULL, NULL);
+
+ nm_clear_l3cd(&priv->l3cd_4);
nm_modem_set_state(NM_MODEM(self),
NM_MODEM_STATE_CONNECTED,
@@ -1040,7 +1040,7 @@ context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
* clear it so that we can gate getting the IP config from oFono
* on whether or not we have already received them
*/
- g_clear_object(&priv->ip4_config);
+ nm_clear_l3cd(&priv->l3cd_4);
/* We need to directly query ConnectionContextinteface to get the current
* property values */
@@ -1258,7 +1258,7 @@ dispose(GObject *object)
priv->connect_properties = NULL;
}
- g_clear_object(&priv->ip4_config);
+ nm_clear_l3cd(&priv->l3cd_4);
if (priv->modem_proxy) {
g_signal_handlers_disconnect_by_data(priv->modem_proxy, self);
diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c
index 15baa677ca..397c2f580b 100644
--- a/src/core/devices/wwan/nm-modem.c
+++ b/src/core/devices/wwan/nm-modem.c
@@ -20,8 +20,7 @@
#include "devices/nm-device-private.h"
#include "nm-netns.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
+#include "nm-l3-config-data.h"
#include "ppp/nm-ppp-manager-call.h"
#include "ppp/nm-ppp-status.h"
@@ -45,8 +44,7 @@ enum {
PPP_STATS,
PPP_FAILED,
PREPARE_RESULT,
- IP4_CONFIG_RESULT,
- IP6_CONFIG_RESULT,
+ NEW_CONFIG,
AUTH_REQUESTED,
AUTH_RESULT,
REMOVED,
@@ -67,18 +65,17 @@ typedef struct _NMModemPrivate {
* We should rework the code that it's not necessary */
char *ip_iface;
- int ip_ifindex;
- NMModemIPMethod ip4_method;
- NMModemIPMethod ip6_method;
- NMUtilsIPv6IfaceId iid;
- NMModemState state;
- NMModemState prev_state; /* revert to this state if enable/disable fails */
- char * device_id;
- char * sim_id;
- NMModemIPType ip_types;
- char * sim_operator_id;
- char * operator_code;
- char * apn;
+ int ip_ifindex;
+ NMModemIPMethod ip4_method;
+ NMModemIPMethod ip6_method;
+ NMModemState state;
+ NMModemState prev_state; /* revert to this state if enable/disable fails */
+ char * device_id;
+ char * sim_id;
+ NMModemIPType ip_types;
+ char * sim_operator_id;
+ char * operator_code;
+ char * apn;
NMPPPManager *ppp_manager;
@@ -88,11 +85,6 @@ typedef struct _NMModemPrivate {
guint mm_ip_timeout;
- guint32 ip4_route_table;
- guint32 ip4_route_metric;
- guint32 ip6_route_table;
- guint32 ip6_route_metric;
-
/* PPP stats */
guint32 in_bytes;
guint32 out_bytes;
@@ -180,6 +172,41 @@ nm_modem_state_to_string(NMModemState state)
/*****************************************************************************/
+void
+nm_modem_emit_signal_new_config(NMModem * self,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ gboolean do_slaac,
+ const NMUtilsIPv6IfaceId *iid,
+ GError * error)
+{
+ nm_assert(NM_IS_MODEM(self));
+ nm_assert_addr_family(addr_family);
+ nm_assert(!l3cd || NM_IS_L3_CONFIG_DATA(l3cd));
+ nm_assert(!do_slaac || addr_family == AF_INET6);
+ nm_assert(!iid || addr_family == AF_INET6);
+ nm_assert(!error || (!l3cd && !do_slaac && !iid));
+
+ if (error) {
+ do_slaac = FALSE;
+ l3cd = NULL;
+ iid = NULL;
+ goto out_emit;
+ }
+
+ if (addr_family == AF_INET6) {
+ do_slaac = !!do_slaac;
+ } else {
+ iid = NULL;
+ do_slaac = FALSE;
+ }
+ if (l3cd)
+ nm_l3_config_data_seal(l3cd);
+
+out_emit:
+ g_signal_emit(self, signals[NEW_CONFIG], 0, addr_family, l3cd, do_slaac, iid, error);
+}
+
gboolean
nm_modem_is_claimed(NMModem *self)
{
@@ -523,66 +550,73 @@ ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpoin
}
static void
-ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data)
+ppp_new_config(NMPPPManager * ppp_manager,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ const NMUtilsIPv6IfaceId *iid,
+ gpointer user_data)
{
- NMModem *self = NM_MODEM(user_data);
- guint32 i, num;
- guint32 bad_dns1 = htonl(0x0A0B0C0D);
- guint32 good_dns1 = htonl(0x04020201); /* GTE nameserver */
- guint32 bad_dns2 = htonl(0x0A0B0C0E);
- guint32 good_dns2 = htonl(0x04020202); /* GTE nameserver */
- gboolean dns_workaround = FALSE;
-
- /* Work around a PPP bug (#1732) which causes many mobile broadband
- * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers.
- * Apparently fixed in ppp-2.4.5 but we've had some reports that this is
- * not the case.
- *
- * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6
- * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e
- */
-
- num = nm_ip4_config_get_num_nameservers(config);
- if (num == 2) {
- gboolean found1 = FALSE, found2 = FALSE;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd_modified = NULL;
+ NMModem * self = NM_MODEM(user_data);
+ gboolean do_slaac = FALSE;
- for (i = 0; i < num; i++) {
- guint32 ns = nm_ip4_config_get_nameserver(config, i);
+ nm_assert_addr_family(addr_family);
- if (ns == bad_dns1)
- found1 = TRUE;
- else if (ns == bad_dns2)
- found2 = TRUE;
+ if (addr_family == AF_INET6) {
+ if (!l3cd)
+ do_slaac = TRUE;
+ else {
+ do_slaac = !!nm_l3_config_data_get_first_obj(l3cd,
+ NMP_OBJECT_TYPE_IP6_ADDRESS,
+ nmp_object_ip6_address_is_not_link_local);
+ }
+ } else {
+ nm_assert(!iid);
+ iid = NULL;
+
+ if (l3cd) {
+ const in_addr_t bad_dns1 = htonl(0x0A0B0C0D);
+ const in_addr_t good_dns1 = htonl(0x04020201); /* GTE nameserver */
+ const in_addr_t bad_dns2 = htonl(0x0A0B0C0E);
+ const in_addr_t good_dns2 = htonl(0x04020202); /* GTE nameserver */
+ gboolean dns_workaround = FALSE;
+ const in_addr_t *addrs;
+ guint num;
+
+ /* Work around a PPP bug (#1732) which causes many mobile broadband
+ * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers.
+ * Apparently fixed in ppp-2.4.5 but we've had some reports that this is
+ * not the case.
+ *
+ * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6
+ * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e
+ */
+
+ addrs = nm_l3_config_data_get_nameservers(l3cd, AF_INET, &num);
+ if (num == 0)
+ dns_workaround = TRUE;
+ else if (num == 2) {
+ /* Be somewhat conservative about substitutions; the "bad" nameservers
+ * could actually be valid in some cases, so only substitute if ppp
+ * returns *only* the two bad nameservers.
+ */
+ dns_workaround = (addrs[0] == bad_dns1 && addrs[1] == bad_dns2)
+ || (addrs[1] == bad_dns1 && addrs[0] == bad_dns2);
+ } else
+ dns_workaround = FALSE;
+
+ if (dns_workaround) {
+ _LOGW("compensating for invalid PPP-provided nameservers");
+ l3cd_modified = nm_l3_config_data_new_clone(l3cd, 0);
+ nm_l3_config_data_clear_nameservers(l3cd_modified, AF_INET);
+ nm_l3_config_data_add_nameserver(l3cd_modified, AF_INET, &good_dns1);
+ nm_l3_config_data_add_nameserver(l3cd_modified, AF_INET, &good_dns2);
+ l3cd = nm_l3_config_data_seal(l3cd_modified);
+ }
}
-
- /* Be somewhat conservative about substitutions; the "bad" nameservers
- * could actually be valid in some cases, so only substitute if ppp
- * returns *only* the two bad nameservers.
- */
- dns_workaround = (found1 && found2);
- }
-
- if (!num || dns_workaround) {
- _LOGW("compensating for invalid PPP-provided nameservers");
- nm_ip4_config_reset_nameservers(config);
- nm_ip4_config_add_nameserver(config, good_dns1);
- nm_ip4_config_add_nameserver(config, good_dns2);
}
- g_signal_emit(self, signals[IP4_CONFIG_RESULT], 0, config, NULL);
-}
-
-static void
-ppp_ip6_config(NMPPPManager * ppp_manager,
- const NMUtilsIPv6IfaceId *iid,
- NMIP6Config * config,
- gpointer user_data)
-{
- NMModem *self = NM_MODEM(user_data);
-
- NM_MODEM_GET_PRIVATE(self)->iid = *iid;
-
- nm_modem_emit_ip6_config_result(self, config, NULL);
+ nm_modem_emit_signal_new_config(self, addr_family, l3cd, do_slaac, iid, NULL);
}
static void
@@ -679,14 +713,6 @@ ppp_stage3_ip_config_start(NMModem * self,
priv->ppp_manager = nm_ppp_manager_create(priv->data_port, &error);
- if (priv->ppp_manager) {
- nm_ppp_manager_set_route_parameters(priv->ppp_manager,
- priv->ip4_route_table,
- priv->ip4_route_metric,
- priv->ip6_route_table,
- priv->ip6_route_metric);
- }
-
if (!priv->ppp_manager
|| !nm_ppp_manager_start(priv->ppp_manager,
req,
@@ -710,12 +736,8 @@ ppp_stage3_ip_config_start(NMModem * self,
G_CALLBACK(ppp_ifindex_set),
self);
g_signal_connect(priv->ppp_manager,
- NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
- G_CALLBACK(ppp_ip4_config),
- self);
- g_signal_connect(priv->ppp_manager,
- NM_PPP_MANAGER_SIGNAL_IP6_CONFIG,
- G_CALLBACK(ppp_ip6_config),
+ NM_PPP_MANAGER_SIGNAL_NEW_CONFIG,
+ G_CALLBACK(ppp_new_config),
self);
g_signal_connect(priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATS, G_CALLBACK(ppp_stats), self);
@@ -748,8 +770,6 @@ nm_modem_stage3_ip4_config_start(NMModem * self,
connection = nm_act_request_get_applied_connection(req);
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
- nm_modem_set_route_parameters_from_device(self, device);
-
method = nm_utils_get_ip_config_method(connection, AF_INET);
/* Only Disabled and Auto methods make sense for WWAN */
@@ -786,9 +806,11 @@ nm_modem_stage3_ip4_config_start(NMModem * self,
}
void
-nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config)
+nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device)
{
- NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(modem);
+ //XXX
+#if 0
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (modem);
/* If the modem has an ethernet-type data interface (ie, not PPP and thus
* not point-to-point) and IP config has a /32 prefix, then we assume that
@@ -805,40 +827,11 @@ nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config)
IFF_NOARP,
TRUE);
}
+#endif
}
/*****************************************************************************/
-void
-nm_modem_emit_ip6_config_result(NMModem *self, NMIP6Config *config, GError *error)
-{
- NMModemPrivate * priv = NM_MODEM_GET_PRIVATE(self);
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *addr;
- gboolean do_slaac = TRUE;
-
- if (error) {
- g_signal_emit(self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error);
- return;
- }
-
- if (config) {
- /* If the IPv6 configuration only included a Link-Local address, then
- * we have to run SLAAC to get the full IPv6 configuration.
- */
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, config, &addr) {
- if (IN6_IS_ADDR_LINKLOCAL(&addr->address)) {
- if (!priv->iid.id)
- priv->iid.id = ((guint64 *) (&addr->address.s6_addr))[1];
- } else
- do_slaac = FALSE;
- }
- }
- g_assert(config || do_slaac);
-
- g_signal_emit(self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL);
-}
-
static NMActStageReturn
stage3_ip6_config_request(NMModem *self, NMDeviceStateReason *out_failure_reason)
{
@@ -865,8 +858,6 @@ nm_modem_stage3_ip6_config_start(NMModem * self,
connection = nm_act_request_get_applied_connection(req);
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
- nm_modem_set_route_parameters_from_device(self, device);
-
method = nm_utils_get_ip_config_method(connection, AF_INET6);
/* Only Ignore, Disabled and Auto methods make sense for WWAN */
@@ -1539,82 +1530,6 @@ nm_modem_owns_port(NMModem *self, const char *iface)
return NM_IN_STRSET(iface, priv->ip_iface, priv->data_port, priv->control_port);
}
-gboolean
-nm_modem_get_iid(NMModem *self, NMUtilsIPv6IfaceId *out_iid)
-{
- g_return_val_if_fail(NM_IS_MODEM(self), FALSE);
-
- *out_iid = NM_MODEM_GET_PRIVATE(self)->iid;
- return TRUE;
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_get_route_parameters(NMModem *self,
- guint32 *out_ip4_route_table,
- guint32 *out_ip4_route_metric,
- guint32 *out_ip6_route_table,
- guint32 *out_ip6_route_metric)
-{
- NMModemPrivate *priv;
-
- g_return_if_fail(NM_IS_MODEM(self));
-
- priv = NM_MODEM_GET_PRIVATE(self);
- NM_SET_OUT(out_ip4_route_table, priv->ip4_route_table);
- NM_SET_OUT(out_ip4_route_metric, priv->ip4_route_metric);
- NM_SET_OUT(out_ip6_route_table, priv->ip6_route_table);
- NM_SET_OUT(out_ip6_route_metric, priv->ip6_route_metric);
-}
-
-void
-nm_modem_set_route_parameters(NMModem *self,
- guint32 ip4_route_table,
- guint32 ip4_route_metric,
- guint32 ip6_route_table,
- guint32 ip6_route_metric)
-{
- NMModemPrivate *priv;
-
- g_return_if_fail(NM_IS_MODEM(self));
-
- priv = NM_MODEM_GET_PRIVATE(self);
- if (priv->ip4_route_table != ip4_route_table || priv->ip4_route_metric != ip4_route_metric
- || priv->ip6_route_table != ip6_route_table || priv->ip6_route_metric != ip6_route_metric) {
- priv->ip4_route_table = ip4_route_table;
- priv->ip4_route_metric = ip4_route_metric;
- priv->ip6_route_table = ip6_route_table;
- priv->ip6_route_metric = ip6_route_metric;
-
- _LOGT("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u",
- priv->ip4_route_table,
- priv->ip4_route_metric,
- priv->ip6_route_table,
- priv->ip6_route_metric);
- }
-
- if (priv->ppp_manager) {
- nm_ppp_manager_set_route_parameters(priv->ppp_manager,
- priv->ip4_route_table,
- priv->ip4_route_metric,
- priv->ip6_route_table,
- priv->ip6_route_metric);
- }
-}
-
-void
-nm_modem_set_route_parameters_from_device(NMModem *self, NMDevice *device)
-{
- g_return_if_fail(NM_IS_DEVICE(device));
-
- nm_modem_set_route_parameters(self,
- nm_device_get_route_table(device, AF_INET),
- nm_device_get_route_metric(device, AF_INET),
- nm_device_get_route_table(device, AF_INET6),
- nm_device_get_route_metric(device, AF_INET6));
-}
-
/*****************************************************************************/
void
@@ -1767,11 +1682,7 @@ nm_modem_init(NMModem *self)
self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_MODEM, NMModemPrivate);
priv = self->_priv;
- priv->ip_ifindex = -1;
- priv->ip4_route_table = RT_TABLE_MAIN;
- priv->ip4_route_metric = 700;
- priv->ip6_route_table = RT_TABLE_MAIN;
- priv->ip6_route_metric = 700;
+ priv->ip_ifindex = -1;
}
static void
@@ -1945,43 +1856,27 @@ nm_modem_class_init(NMModemClass *klass)
1,
G_TYPE_UINT);
- signals[IP4_CONFIG_RESULT] = g_signal_new(NM_MODEM_IP4_CONFIG_RESULT,
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 2,
- G_TYPE_OBJECT,
- G_TYPE_POINTER);
-
- /**
- * NMModem::ip6-config-result:
- * @modem: the #NMModem on which the signal is emitted
- * @config: the #NMIP6Config to apply to the modem's data port
- * @do_slaac: %TRUE if IPv6 SLAAC should be started
- * @error: a #GError if any error occurred during IP configuration
- *
- * This signal is emitted when IPv6 configuration has completed or failed.
- * If @error is set the configuration failed. If @config is set, then
+ /*
+ * This signal is emitted when IP configuration has completed or failed.
+ * If @error is set the configuration failed. If @l3cd is set, then
* the details should be applied to the data port before any further
- * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC
- * should be started after applying @config to the data port.
+ * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC
+ * should be started after applying @l3cd to the data port.
*/
- signals[IP6_CONFIG_RESULT] = g_signal_new(NM_MODEM_IP6_CONFIG_RESULT,
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 3,
- G_TYPE_OBJECT,
- G_TYPE_BOOLEAN,
- G_TYPE_POINTER);
+ signals[NEW_CONFIG] = g_signal_new(NM_MODEM_NEW_CONFIG,
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_INT, /* int addr_family */
+ G_TYPE_POINTER, /* const NML3ConfigData *l3cd */
+ G_TYPE_BOOLEAN, /* gboolean do_slaac */
+ G_TYPE_POINTER, /* const NMUtilsIPv6IfaceId *iid */
+ G_TYPE_POINTER); /* GError *error */
signals[PREPARE_RESULT] = g_signal_new(NM_MODEM_PREPARE_RESULT,
G_OBJECT_CLASS_TYPE(object_class),
diff --git a/src/core/devices/wwan/nm-modem.h b/src/core/devices/wwan/nm-modem.h
index 87162cfca7..95f66a8d6e 100644
--- a/src/core/devices/wwan/nm-modem.h
+++ b/src/core/devices/wwan/nm-modem.h
@@ -32,15 +32,14 @@
#define NM_MODEM_APN "apn"
/* Signals */
-#define NM_MODEM_PPP_STATS "ppp-stats"
-#define NM_MODEM_PPP_FAILED "ppp-failed"
-#define NM_MODEM_PREPARE_RESULT "prepare-result"
-#define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result"
-#define NM_MODEM_IP6_CONFIG_RESULT "ip6-config-result"
-#define NM_MODEM_AUTH_REQUESTED "auth-requested"
-#define NM_MODEM_AUTH_RESULT "auth-result"
-#define NM_MODEM_REMOVED "removed"
-#define NM_MODEM_STATE_CHANGED "state-changed"
+#define NM_MODEM_PPP_STATS "ppp-stats"
+#define NM_MODEM_PPP_FAILED "ppp-failed"
+#define NM_MODEM_PREPARE_RESULT "prepare-result"
+#define NM_MODEM_NEW_CONFIG "new-config"
+#define NM_MODEM_AUTH_REQUESTED "auth-requested"
+#define NM_MODEM_AUTH_RESULT "auth-result"
+#define NM_MODEM_REMOVED "removed"
+#define NM_MODEM_STATE_CHANGED "state-changed"
typedef enum {
NM_MODEM_IP_METHOD_UNKNOWN = 0,
@@ -161,7 +160,6 @@ const char *nm_modem_get_driver(NMModem *modem);
const char *nm_modem_get_device_id(NMModem *modem);
const char *nm_modem_get_sim_id(NMModem *modem);
const char *nm_modem_get_sim_operator_id(NMModem *modem);
-gboolean nm_modem_get_iid(NMModem *modem, NMUtilsIPv6IfaceId *out_iid);
const char *nm_modem_get_operator_code(NMModem *modem);
const char *nm_modem_get_apn(NMModem *modem);
@@ -188,20 +186,6 @@ gboolean nm_modem_complete_connection(NMModem * self,
NMConnection *const *existing_connections,
GError ** error);
-void nm_modem_get_route_parameters(NMModem *self,
- guint32 *out_ip4_route_table,
- guint32 *out_ip4_route_metric,
- guint32 *out_ip6_route_table,
- guint32 *out_ip6_route_metric);
-
-void nm_modem_set_route_parameters(NMModem *self,
- guint32 ip4_route_table,
- guint32 ip4_route_metric,
- guint32 ip6_route_table,
- guint32 ip6_route_metric);
-
-void nm_modem_set_route_parameters_from_device(NMModem *modem, NMDevice *device);
-
NMActStageReturn nm_modem_act_stage1_prepare(NMModem * modem,
NMActRequest * req,
NMDeviceStateReason *out_failure_reason);
@@ -217,7 +201,7 @@ NMActStageReturn nm_modem_stage3_ip6_config_start(NMModem * modem,
NMDevice * device,
NMDeviceStateReason *out_failure_reason);
-void nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config);
+void nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device);
void nm_modem_get_secrets(NMModem * modem,
const char *setting_name,
@@ -256,7 +240,13 @@ void nm_modem_emit_ppp_failed(NMModem *self, NMDeviceStateReason reason);
GArray *nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError **error);
/* For subclasses */
-void nm_modem_emit_ip6_config_result(NMModem *self, NMIP6Config *config, GError *error);
+
+void nm_modem_emit_signal_new_config(NMModem * self,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ gboolean do_slaac,
+ const NMUtilsIPv6IfaceId *iid,
+ GError * error);
const char *nm_modem_ip_type_to_string(NMModemIPType ip_type);
diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c
index f35091d167..a274e2907b 100644
--- a/src/core/dhcp/nm-dhcp-client.c
+++ b/src/core/dhcp/nm-dhcp-client.c
@@ -20,6 +20,7 @@
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
+#include "nm-l3-config-data.h"
#include "nm-dhcp-utils.h"
#include "nm-dhcp-options.h"
#include "libnm-platform/nm-platform.h"
@@ -41,8 +42,6 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDhcpClient,
PROP_IFACE,
PROP_IFINDEX,
PROP_MULTI_IDX,
- PROP_ROUTE_METRIC,
- PROP_ROUTE_TABLE,
PROP_TIMEOUT,
PROP_UUID,
PROP_IAID,
@@ -70,8 +69,6 @@ typedef struct _NMDhcpClientPrivate {
guint watch_id;
int addr_family;
int ifindex;
- guint32 route_table;
- guint32 route_metric;
guint32 timeout;
guint32 iaid;
NMDhcpState state;
@@ -156,44 +153,6 @@ nm_dhcp_client_get_broadcast_hw_addr(NMDhcpClient *self)
}
guint32
-nm_dhcp_client_get_route_table(NMDhcpClient *self)
-{
- g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), RT_TABLE_MAIN);
-
- return NM_DHCP_CLIENT_GET_PRIVATE(self)->route_table;
-}
-
-void
-nm_dhcp_client_set_route_table(NMDhcpClient *self, guint32 route_table)
-{
- NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
-
- if (route_table != priv->route_table) {
- priv->route_table = route_table;
- _notify(self, PROP_ROUTE_TABLE);
- }
-}
-
-guint32
-nm_dhcp_client_get_route_metric(NMDhcpClient *self)
-{
- g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), G_MAXUINT32);
-
- return NM_DHCP_CLIENT_GET_PRIVATE(self)->route_metric;
-}
-
-void
-nm_dhcp_client_set_route_metric(NMDhcpClient *self, guint32 route_metric)
-{
- NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
-
- if (route_metric != priv->route_metric) {
- priv->route_metric = route_metric;
- _notify(self, PROP_ROUTE_METRIC);
- }
-}
-
-guint32
nm_dhcp_client_get_timeout(NMDhcpClient *self)
{
g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), 0);
@@ -436,20 +395,22 @@ stop(NMDhcpClient *self, gboolean release)
}
void
-nm_dhcp_client_set_state(NMDhcpClient *self,
- NMDhcpState new_state,
- NMIPConfig * ip_config,
- GHashTable * options)
+nm_dhcp_client_set_state(NMDhcpClient *self, NMDhcpState new_state, NML3ConfigData *l3cd)
{
NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
+ GHashTable * options;
+
+ g_return_if_fail(NM_IS_DHCP_CLIENT(self));
if (NM_IN_SET(new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED)) {
- g_return_if_fail(NM_IS_IP_CONFIG_ADDR_FAMILY(ip_config, priv->addr_family));
- g_return_if_fail(options);
- } else {
- g_return_if_fail(!ip_config);
- g_return_if_fail(!options);
- }
+ g_return_if_fail(NM_IS_L3_CONFIG_DATA(l3cd));
+ g_return_if_fail(
+ nm_l3_config_data_get_dhcp_lease(l3cd, nm_dhcp_client_get_addr_family(self)));
+ } else
+ g_return_if_fail(!l3cd);
+
+ if (l3cd)
+ nm_l3_config_data_seal(l3cd);
if (new_state >= NM_DHCP_STATE_BOUND)
timeout_cleanup(self);
@@ -465,22 +426,31 @@ nm_dhcp_client_set_state(NMDhcpClient *self,
&& !NM_IN_SET(new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED))
return;
- if (_LOGD_ENABLED()) {
- gs_free const char **keys = NULL;
- guint i, nkeys;
+ options =
+ l3cd ? nm_dhcp_lease_get_options(nm_l3_config_data_get_dhcp_lease(l3cd, priv->addr_family))
+ : NULL;
- keys = nm_utils_strdict_get_keys(options, TRUE, &nkeys);
- for (i = 0; i < nkeys; i++) {
- _LOGD("option %-20s => '%s'", keys[i], (char *) g_hash_table_lookup(options, keys[i]));
- }
- }
+ if (_LOGD_ENABLED()) {
+ if (options) {
+ gs_free const char **keys = NULL;
+ guint nkeys;
+ guint i;
+
+ keys = nm_utils_strdict_get_keys(options, TRUE, &nkeys);
+ for (i = 0; i < nkeys; i++) {
+ _LOGD("option %-20s => '%s'",
+ keys[i],
+ (char *) g_hash_table_lookup(options, keys[i]));
+ }
- if (_LOGT_ENABLED() && priv->addr_family == AF_INET6) {
- gs_free char *event_id = NULL;
+ if (priv->addr_family == AF_INET6) {
+ gs_free char *event_id = NULL;
- event_id = nm_dhcp_utils_get_dhcp6_event_id(options);
- if (event_id)
- _LOGT("event-id: \"%s\"", event_id);
+ event_id = nm_dhcp_utils_get_dhcp6_event_id(options);
+ if (event_id)
+ _LOGT("event-id: \"%s\"", event_id);
+ }
+ }
}
if (_LOGI_ENABLED()) {
@@ -497,7 +467,7 @@ nm_dhcp_client_set_state(NMDhcpClient *self,
}
priv->state = new_state;
- g_signal_emit(G_OBJECT(self), signals[SIGNAL_STATE_CHANGED], 0, new_state, ip_config, options);
+ g_signal_emit(G_OBJECT(self), signals[SIGNAL_STATE_CHANGED], 0, new_state, l3cd);
}
static gboolean
@@ -508,7 +478,7 @@ transaction_timeout(gpointer user_data)
priv->timeout_id = 0;
_LOGW("request timed out");
- nm_dhcp_client_set_state(self, NM_DHCP_STATE_TIMEOUT, NULL, NULL);
+ nm_dhcp_client_set_state(self, NM_DHCP_STATE_TIMEOUT, NULL);
return G_SOURCE_REMOVE;
}
@@ -534,7 +504,7 @@ daemon_watch_cb(GPid pid, int status, gpointer user_data)
priv->pid = -1;
- nm_dhcp_client_set_state(self, NM_DHCP_STATE_TERMINATED, NULL, NULL);
+ nm_dhcp_client_set_state(self, NM_DHCP_STATE_TERMINATED, NULL);
}
void
@@ -750,7 +720,7 @@ nm_dhcp_client_stop(NMDhcpClient *self, gboolean release)
_LOGI("canceled DHCP transaction");
nm_assert(priv->pid == -1);
- nm_dhcp_client_set_state(self, NM_DHCP_STATE_TERMINATED, NULL, NULL);
+ nm_dhcp_client_set_state(self, NM_DHCP_STATE_TERMINATED, NULL);
}
/*****************************************************************************/
@@ -874,12 +844,11 @@ nm_dhcp_client_handle_event(gpointer unused,
const char * reason,
NMDhcpClient *self)
{
- NMDhcpClientPrivate *priv;
- guint32 old_state;
- guint32 new_state;
- gs_unref_hashtable GHashTable *str_options = NULL;
- gs_unref_object NMIPConfig *ip_config = NULL;
- NMPlatformIP6Address prefix = {
+ NMDhcpClientPrivate * priv;
+ guint32 old_state;
+ guint32 new_state;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMPlatformIP6Address prefix = {
0,
};
@@ -907,9 +876,10 @@ nm_dhcp_client_handle_event(gpointer unused,
return TRUE;
if (NM_IN_SET(new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED)) {
- GVariantIter iter;
- const char * name;
- GVariant * value;
+ gs_unref_hashtable GHashTable *str_options = NULL;
+ GVariantIter iter;
+ const char * name;
+ GVariant * value;
/* Copy options */
str_options = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free);
@@ -922,24 +892,27 @@ nm_dhcp_client_handle_event(gpointer unused,
/* Create the IP config */
if (g_hash_table_size(str_options) > 0) {
if (priv->addr_family == AF_INET) {
- ip_config = NM_IP_CONFIG_CAST(
- nm_dhcp_utils_ip4_config_from_options(nm_dhcp_client_get_multi_idx(self),
- priv->ifindex,
- priv->iface,
- str_options,
- priv->route_table,
- priv->route_metric));
+ l3cd = nm_dhcp_utils_ip4_config_from_options(nm_dhcp_client_get_multi_idx(self),
+ priv->ifindex,
+ priv->iface,
+ str_options);
} else {
- prefix = nm_dhcp_utils_ip6_prefix_from_options(str_options);
- ip_config = NM_IP_CONFIG_CAST(nm_dhcp_utils_ip6_config_from_options(
+ prefix = nm_dhcp_utils_ip6_prefix_from_options(str_options);
+ l3cd = nm_dhcp_utils_ip6_config_from_options(
nm_dhcp_client_get_multi_idx(self),
priv->ifindex,
priv->iface,
str_options,
- NM_FLAGS_HAS(priv->client_flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY)));
+ NM_FLAGS_HAS(priv->client_flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY));
}
} else
g_warn_if_reached();
+
+ if (l3cd) {
+ nm_l3_config_data_set_dhcp_lease_from_options(l3cd,
+ priv->addr_family,
+ g_steal_pointer(&str_options));
+ }
}
if (!IN6_IS_ADDR_UNSPECIFIED(&prefix.address)) {
@@ -947,17 +920,16 @@ nm_dhcp_client_handle_event(gpointer unused,
* of the DHCP client instance. Instead, we just signal the prefix
* to the device. */
nm_dhcp_client_emit_ipv6_prefix_delegated(self, &prefix);
- } else {
- /* Fail if no valid IP config was received */
- if (NM_IN_SET(new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED) && !ip_config) {
- _LOGW("client bound but IP config not received");
- new_state = NM_DHCP_STATE_FAIL;
- nm_clear_pointer(&str_options, g_hash_table_unref);
- }
+ return TRUE;
+ }
- nm_dhcp_client_set_state(self, new_state, ip_config, str_options);
+ /* Fail if no valid IP config was received */
+ if (NM_IN_SET(new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED) && !l3cd) {
+ _LOGW("client bound but IP config not received");
+ new_state = NM_DHCP_STATE_FAIL;
}
+ nm_dhcp_client_set_state(self, new_state, l3cd);
return TRUE;
}
@@ -1028,12 +1000,6 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
case PROP_HOSTNAME:
g_value_set_string(value, priv->hostname);
break;
- case PROP_ROUTE_METRIC:
- g_value_set_uint(value, priv->route_metric);
- break;
- case PROP_ROUTE_TABLE:
- g_value_set_uint(value, priv->route_table);
- break;
case PROP_TIMEOUT:
g_value_set_uint(value, priv->timeout);
break;
@@ -1116,12 +1082,6 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
/* construct-only */
priv->mud_url = g_value_dup_string(value);
break;
- case PROP_ROUTE_TABLE:
- priv->route_table = g_value_get_uint(value);
- break;
- case PROP_ROUTE_METRIC:
- priv->route_metric = g_value_get_uint(value);
- break;
case PROP_TIMEOUT:
/* construct-only */
priv->timeout = g_value_get_uint(value);
@@ -1324,24 +1284,6 @@ nm_dhcp_client_class_init(NMDhcpClientClass *client_class)
NULL,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ROUTE_TABLE] =
- g_param_spec_uint(NM_DHCP_CLIENT_ROUTE_TABLE,
- "",
- "",
- 0,
- G_MAXUINT32,
- RT_TABLE_MAIN,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_ROUTE_METRIC] =
- g_param_spec_uint(NM_DHCP_CLIENT_ROUTE_METRIC,
- "",
- "",
- 0,
- G_MAXUINT32,
- 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
G_STATIC_ASSERT_EXPR(G_MAXINT32 == NM_DHCP_TIMEOUT_INFINITY);
obj_properties[PROP_TIMEOUT] =
g_param_spec_uint(NM_DHCP_CLIENT_TIMEOUT,
@@ -1385,10 +1327,9 @@ nm_dhcp_client_class_init(NMDhcpClientClass *client_class)
NULL,
NULL,
G_TYPE_NONE,
- 3,
+ 2,
G_TYPE_UINT,
- G_TYPE_OBJECT,
- G_TYPE_HASH_TABLE);
+ G_TYPE_POINTER /* NML3ConfigData */);
signals[SIGNAL_PREFIX_DELEGATED] = g_signal_new(NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED,
G_OBJECT_CLASS_TYPE(object_class),
diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h
index 3fe1b34ec9..fccbf7d560 100644
--- a/src/core/dhcp/nm-dhcp-client.h
+++ b/src/core/dhcp/nm-dhcp-client.h
@@ -8,8 +8,6 @@
#include "nm-setting-ip4-config.h"
#include "nm-setting-ip6-config.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
#include "nm-dhcp-utils.h"
#define NM_DHCP_TIMEOUT_DEFAULT ((guint32) 45) /* default DHCP timeout, in seconds */
@@ -34,8 +32,6 @@
#define NM_DHCP_CLIENT_MULTI_IDX "multi-idx"
#define NM_DHCP_CLIENT_HOSTNAME "hostname"
#define NM_DHCP_CLIENT_MUD_URL "mud-url"
-#define NM_DHCP_CLIENT_ROUTE_METRIC "route-metric"
-#define NM_DHCP_CLIENT_ROUTE_TABLE "route-table"
#define NM_DHCP_CLIENT_TIMEOUT "timeout"
#define NM_DHCP_CLIENT_UUID "uuid"
#define NM_DHCP_CLIENT_IAID "iaid"
@@ -133,14 +129,6 @@ GBytes *nm_dhcp_client_get_broadcast_hw_addr(NMDhcpClient *self);
const char *nm_dhcp_client_get_anycast_address(NMDhcpClient *self);
-guint32 nm_dhcp_client_get_route_table(NMDhcpClient *self);
-
-void nm_dhcp_client_set_route_table(NMDhcpClient *self, guint32 route_table);
-
-guint32 nm_dhcp_client_get_route_metric(NMDhcpClient *self);
-
-void nm_dhcp_client_set_route_metric(NMDhcpClient *self, guint32 route_metric);
-
guint32 nm_dhcp_client_get_timeout(NMDhcpClient *self);
guint32 nm_dhcp_client_get_iaid(NMDhcpClient *self);
@@ -189,10 +177,7 @@ void nm_dhcp_client_watch_child(NMDhcpClient *self, pid_t pid);
void nm_dhcp_client_stop_watch_child(NMDhcpClient *self, pid_t pid);
-void nm_dhcp_client_set_state(NMDhcpClient *self,
- NMDhcpState new_state,
- NMIPConfig * ip_config,
- GHashTable * options); /* str:str hash */
+void nm_dhcp_client_set_state(NMDhcpClient *self, NMDhcpState new_state, NML3ConfigData *l3cd);
gboolean nm_dhcp_client_handle_event(gpointer unused,
const char * iface,
diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c
index 4284a852a5..6f1df27225 100644
--- a/src/core/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c
@@ -15,7 +15,6 @@
#include "libnm-glib-aux/nm-dedup-multi.h"
#include "nm-dhcp-utils.h"
-#include "nm-ip4-config.h"
#include "nm-utils.h"
#include "libnm-platform/nm-platform.h"
#include "NetworkManagerUtils.h"
diff --git a/src/core/dhcp/nm-dhcp-manager.c b/src/core/dhcp/nm-dhcp-manager.c
index 44b8ede2c0..f62e411d01 100644
--- a/src/core/dhcp/nm-dhcp-manager.c
+++ b/src/core/dhcp/nm-dhcp-manager.c
@@ -45,11 +45,10 @@ G_DEFINE_TYPE(NMDhcpManager, nm_dhcp_manager, G_TYPE_OBJECT)
/*****************************************************************************/
-static void client_state_changed(NMDhcpClient * client,
- NMDhcpState state,
- GObject * ip_config,
- GVariant * options,
- NMDhcpManager *self);
+static void client_state_changed(NMDhcpClient * client,
+ NMDhcpState state,
+ NML3ConfigData *l3cd,
+ NMDhcpManager * self);
/*****************************************************************************/
@@ -186,11 +185,10 @@ remove_client_unref(NMDhcpManager *self, NMDhcpClient *client)
}
static void
-client_state_changed(NMDhcpClient * client,
- NMDhcpState state,
- GObject * ip_config,
- GVariant * options,
- NMDhcpManager *self)
+client_state_changed(NMDhcpClient * client,
+ NMDhcpState state,
+ NML3ConfigData *l3cd,
+ NMDhcpManager * self)
{
if (state >= NM_DHCP_STATE_TIMEOUT)
remove_client_unref(self, client);
@@ -205,8 +203,6 @@ client_start(NMDhcpManager * self,
GBytes * hwaddr,
GBytes * bcast_hwaddr,
const char * uuid,
- guint32 route_table,
- guint32 route_metric,
const struct in6_addr * ipv6_ll_addr,
GBytes * dhcp_client_id,
gboolean enforce_duid,
@@ -323,10 +319,6 @@ client_start(NMDhcpManager * self,
hostname,
NM_DHCP_CLIENT_MUD_URL,
mud_url,
- NM_DHCP_CLIENT_ROUTE_TABLE,
- (guint) route_table,
- NM_DHCP_CLIENT_ROUTE_METRIC,
- (guint) route_metric,
NM_DHCP_CLIENT_TIMEOUT,
(guint) timeout,
NM_DHCP_CLIENT_HOSTNAME_FLAGS,
@@ -402,8 +394,6 @@ nm_dhcp_manager_start_ip4(NMDhcpManager * self,
GBytes * hwaddr,
GBytes * bcast_hwaddr,
const char * uuid,
- guint32 route_table,
- guint32 route_metric,
NMDhcpClientFlags client_flags,
gboolean send_hostname,
const char * dhcp_hostname,
@@ -463,8 +453,6 @@ nm_dhcp_manager_start_ip4(NMDhcpManager * self,
hwaddr,
bcast_hwaddr,
uuid,
- route_table,
- route_metric,
NULL,
dhcp_client_id,
FALSE,
@@ -492,8 +480,6 @@ nm_dhcp_manager_start_ip6(NMDhcpManager * self,
int ifindex,
const struct in6_addr * ll_addr,
const char * uuid,
- guint32 route_table,
- guint32 route_metric,
NMDhcpClientFlags client_flags,
gboolean send_hostname,
const char * dhcp_hostname,
@@ -530,8 +516,6 @@ nm_dhcp_manager_start_ip6(NMDhcpManager * self,
NULL,
NULL,
uuid,
- route_table,
- route_metric,
ll_addr,
duid,
enforce_duid,
diff --git a/src/core/dhcp/nm-dhcp-manager.h b/src/core/dhcp/nm-dhcp-manager.h
index ce160437a5..ab44158cee 100644
--- a/src/core/dhcp/nm-dhcp-manager.h
+++ b/src/core/dhcp/nm-dhcp-manager.h
@@ -8,7 +8,6 @@
#define __NETWORKMANAGER_DHCP_MANAGER_H__
#include "nm-dhcp-client.h"
-#include "nm-ip4-config.h"
#include "nm-dhcp-config.h"
#define NM_TYPE_DHCP_MANAGER (nm_dhcp_manager_get_type())
@@ -39,8 +38,6 @@ NMDhcpClient *nm_dhcp_manager_start_ip4(NMDhcpManager * manager,
GBytes * hwaddr,
GBytes * bcast_hwaddr,
const char * uuid,
- guint32 route_table,
- guint32 route_metric,
NMDhcpClientFlags client_flags,
gboolean send_hostname,
const char * dhcp_hostname,
@@ -61,8 +58,6 @@ NMDhcpClient *nm_dhcp_manager_start_ip6(NMDhcpManager * manager,
int ifindex,
const struct in6_addr * ll_addr,
const char * uuid,
- guint32 route_table,
- guint32 route_metric,
NMDhcpClientFlags client_flags,
gboolean send_hostname,
const char * dhcp_hostname,
diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c
index fe71f587a4..699324fca4 100644
--- a/src/core/dhcp/nm-dhcp-nettools.c
+++ b/src/core/dhcp/nm-dhcp-nettools.c
@@ -17,6 +17,7 @@
#include "libnm-std-aux/unaligned.h"
#include "libnm-glib-aux/nm-str-buf.h"
+#include "nm-l3-config-data.h"
#include "nm-utils.h"
#include "nm-config.h"
#include "nm-dhcp-utils.h"
@@ -151,7 +152,7 @@ lease_option_consume_route(const uint8_t **datap,
static gboolean
lease_parse_address(NDhcp4ClientLease *lease,
- NMIP4Config * ip4_config,
+ NML3ConfigData * l3cd,
GHashTable * options,
GError ** error)
{
@@ -256,23 +257,23 @@ lease_parse_address(NDhcp4ClientLease *lease,
a_next_server.s_addr);
}
- nm_ip4_config_add_address(ip4_config,
- &((const NMPlatformIP4Address){
- .address = a_address.s_addr,
- .peer_address = a_address.s_addr,
- .plen = a_plen,
- .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
- .timestamp = a_timestamp,
- .lifetime = a_lifetime,
- .preferred = a_lifetime,
- }));
+ nm_l3_config_data_add_address_4(l3cd,
+ &((const NMPlatformIP4Address){
+ .address = a_address.s_addr,
+ .peer_address = a_address.s_addr,
+ .plen = a_plen,
+ .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .timestamp = a_timestamp,
+ .lifetime = a_lifetime,
+ .preferred = a_lifetime,
+ }));
return TRUE;
}
static void
lease_parse_address_list(NDhcp4ClientLease * lease,
- NMIP4Config * ip4_config,
+ NML3ConfigData * l3cd,
NMDhcpOptionDhcp4Options option,
GHashTable * options,
NMStrBuf * sbuf)
@@ -304,13 +305,13 @@ lease_parse_address_list(NDhcp4ClientLease * lease,
* See https://github.com/systemd/systemd/issues/4524. */
continue;
}
- nm_ip4_config_add_nameserver(ip4_config, addr);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET, &addr);
break;
case NM_DHCP_OPTION_DHCP4_NIS_SERVERS:
- nm_ip4_config_add_nis_server(ip4_config, addr);
+ nm_l3_config_data_add_nis_server(l3cd, addr);
break;
case NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER:
- nm_ip4_config_add_wins(ip4_config, addr);
+ nm_l3_config_data_add_wins(l3cd, addr);
break;
case NM_DHCP_OPTION_DHCP4_NTP_SERVER:
break;
@@ -324,10 +325,8 @@ lease_parse_address_list(NDhcp4ClientLease * lease,
static void
lease_parse_routes(NDhcp4ClientLease *lease,
- NMIP4Config * ip4_config,
+ NML3ConfigData * l3cd,
GHashTable * options,
- guint32 route_table,
- guint32 route_metric,
NMStrBuf * sbuf)
{
char dest_str[NM_UTILS_INET_ADDRSTRLEN];
@@ -336,9 +335,9 @@ lease_parse_routes(NDhcp4ClientLease *lease,
in_addr_t gateway;
uint8_t plen;
guint32 m;
- gboolean has_router_from_classless = FALSE;
- gboolean has_classless = FALSE;
- guint32 default_route_metric = route_metric;
+ gboolean has_router_from_classless = FALSE;
+ gboolean has_classless = FALSE;
+ guint32 default_route_metric_offset = 0;
const guint8 *l_data;
gsize l_data_len;
int r;
@@ -367,26 +366,22 @@ lease_parse_routes(NDhcp4ClientLease *lease,
if (plen == 0) {
/* if there are multiple default routes, we add them with differing
* metrics. */
- m = default_route_metric;
- if (default_route_metric < G_MAXUINT32)
- default_route_metric++;
-
+ m = default_route_metric_offset++;
has_router_from_classless = TRUE;
- } else {
- m = route_metric;
- }
-
- nm_ip4_config_add_route(
- ip4_config,
- &((const NMPlatformIP4Route){
- .network = dest,
- .plen = plen,
- .gateway = gateway,
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .metric = m,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- }),
- NULL);
+ } else
+ m = 0;
+
+ nm_l3_config_data_add_route_4(l3cd,
+ &((const NMPlatformIP4Route){
+ .network = dest,
+ .plen = plen,
+ .gateway = gateway,
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = m,
+ }));
}
has_classless = TRUE;
@@ -419,17 +414,17 @@ lease_parse_routes(NDhcp4ClientLease *lease,
continue;
}
- nm_ip4_config_add_route(
- ip4_config,
- &((const NMPlatformIP4Route){
- .network = dest,
- .plen = plen,
- .gateway = gateway,
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .metric = route_metric,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- }),
- NULL);
+ nm_l3_config_data_add_route_4(l3cd,
+ &((const NMPlatformIP4Route){
+ .network = dest,
+ .plen = plen,
+ .gateway = gateway,
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
+ }));
}
nm_dhcp_option_add_option(options,
@@ -463,19 +458,17 @@ lease_parse_routes(NDhcp4ClientLease *lease,
/* if there are multiple default routes, we add them with differing
* metrics. */
- m = default_route_metric;
- if (default_route_metric < G_MAXUINT32)
- default_route_metric++;
-
- nm_ip4_config_add_route(
- ip4_config,
- &((const NMPlatformIP4Route){
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .gateway = gateway,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = m,
- }),
- NULL);
+ m = default_route_metric_offset++;
+
+ nm_l3_config_data_add_route_4(l3cd,
+ &((const NMPlatformIP4Route){
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .gateway = gateway,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = m,
+ }));
}
nm_dhcp_option_add_option(options,
@@ -486,7 +479,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}
static void
-lease_parse_search_domains(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GHashTable *options)
+lease_parse_search_domains(NDhcp4ClientLease *lease, NML3ConfigData *l3cd, GHashTable *options)
{
gs_strfreev char **domains = NULL;
const guint8 * l_data;
@@ -504,7 +497,7 @@ lease_parse_search_domains(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GH
return;
for (i = 0; domains[i]; i++)
- nm_ip4_config_add_search(ip4_config, domains[i]);
+ nm_l3_config_data_add_search(l3cd, AF_INET, domains[i]);
nm_dhcp_option_take_option(options,
AF_INET,
@@ -539,34 +532,33 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options)
}
}
-static NMIP4Config *
+static NML3ConfigData *
lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
const char * iface,
int ifindex,
NDhcp4ClientLease *lease,
- guint32 route_table,
- guint32 route_metric,
- GHashTable ** out_options,
GError ** error)
{
- nm_auto_str_buf NMStrBuf sbuf = NM_STR_BUF_INIT(0, FALSE);
- gs_unref_object NMIP4Config *ip4_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_str_buf NMStrBuf sbuf = NM_STR_BUF_INIT(0, FALSE);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
const guint8 * l_data;
gsize l_data_len;
const char * v_str;
guint16 v_u16;
- gboolean v_bool;
in_addr_t v_inaddr;
struct in_addr v_inaddr_s;
int r;
g_return_val_if_fail(lease != NULL, NULL);
- ip4_config = nm_ip4_config_new(multi_idx, ifindex);
- options = nm_dhcp_option_create_options_dict();
+ l3cd = nm_l3_config_data_new(multi_idx, ifindex);
- if (!lease_parse_address(lease, ip4_config, options, error))
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_DHCP);
+
+ options = nm_dhcp_option_create_options_dict();
+
+ if (!lease_parse_address(lease, l3cd, options, error))
return NULL;
r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s);
@@ -585,13 +577,9 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
v_inaddr);
}
- lease_parse_routes(lease, ip4_config, options, route_table, route_metric, &sbuf);
+ lease_parse_routes(lease, l3cd, options, &sbuf);
- lease_parse_address_list(lease,
- ip4_config,
- NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER,
- options,
- &sbuf);
+ lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options, &sbuf);
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, &l_data, &l_data_len);
if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) {
@@ -616,7 +604,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_str_buf_append_required_delimiter(&sbuf, ' ');
nm_str_buf_append(&sbuf, s);
- nm_ip4_config_add_domain(ip4_config, s);
+ nm_l3_config_data_add_domain(l3cd, AF_INET, s);
}
}
@@ -628,18 +616,17 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
}
}
- lease_parse_search_domains(lease, ip4_config, options);
+ lease_parse_search_domains(lease, l3cd, options);
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, &l_data, &l_data_len);
if (r == 0 && nm_dhcp_lease_data_parse_mtu(l_data, l_data_len, &v_u16)) {
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, v_u16);
- nm_ip4_config_set_mtu(ip4_config, v_u16, NM_IP_CONFIG_SOURCE_DHCP);
+ nm_l3_config_data_set_mtu(l3cd, v_u16);
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC, &l_data, &l_data_len);
- v_bool =
- (r == 0) && memmem(l_data, l_data_len, "ANDROID_METERED", NM_STRLEN("ANDROID_METERED"));
- nm_ip4_config_set_metered(ip4_config, v_bool);
+ if ((r == 0) && memmem(l_data, l_data_len, "ANDROID_METERED", NM_STRLEN("ANDROID_METERED")))
+ nm_l3_config_data_set_metered(l3cd, TRUE);
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_HOST_NAME, &l_data, &l_data_len);
if (r == 0) {
@@ -650,7 +637,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
}
}
- lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NTP_SERVER, options, &sbuf);
+ lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_NTP_SERVER, options, &sbuf);
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROOT_PATH, &l_data, &l_data_len);
if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) {
@@ -681,11 +668,17 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
* We reject NUL characters inside the string (except trailing NULs).
* Otherwise, we allow any encoding and backslash-escape the result to
* UTF-8. */
- nm_dhcp_option_add_option_utf8safe_escape(options,
- AF_INET,
- NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
- l_data,
- l_data_len);
+ gs_free char *to_free = NULL;
+ const char * escaped;
+
+ escaped = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
+ nm_dhcp_option_add_option(options,
+ AF_INET,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
+ escaped ?: "");
+
+ nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO);
+ nm_l3_config_data_set_proxy_pac_url(l3cd, escaped ?: "");
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, &l_data, &l_data_len);
@@ -697,21 +690,20 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
v_str = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: "");
- nm_ip4_config_set_nis_domain(ip4_config, v_str ?: "");
+ nm_l3_config_data_set_nis_domain(l3cd, v_str ?: "");
}
- lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf);
+ lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf);
- lease_parse_address_list(lease,
- ip4_config,
- NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER,
- options,
- &sbuf);
+ lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, options, &sbuf);
lease_parse_private_options(lease, options);
- NM_SET_OUT(out_options, g_steal_pointer(&options));
- return g_steal_pointer(&ip4_config);
+ nm_dhcp_option_add_requests_to_options(options, AF_INET);
+
+ nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET, g_steal_pointer(&options));
+
+ return g_steal_pointer(&l3cd);
}
/*****************************************************************************/
@@ -743,36 +735,30 @@ lease_save(NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_fil
static void
bound4_handle(NMDhcpNettools *self, NDhcp4ClientLease *lease, gboolean extended)
{
- NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
- const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
- gs_unref_object NMIP4Config *ip4_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
- GError * error = NULL;
+ NMDhcpNettoolsPrivate * priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self);
+ const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ GError * error = NULL;
_LOGT("lease available (%s)", extended ? "extended" : "new");
- ip4_config = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
- iface,
- nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
- lease,
- nm_dhcp_client_get_route_table(NM_DHCP_CLIENT(self)),
- nm_dhcp_client_get_route_metric(NM_DHCP_CLIENT(self)),
- &options,
- &error);
- if (!ip4_config) {
- _LOGW("%s", error->message);
+ l3cd = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
+ iface,
+ nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
+ lease,
+ &error);
+ if (!l3cd) {
+ _LOGW("failure to parse lease: %s", error->message);
g_clear_error(&error);
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
- nm_dhcp_option_add_requests_to_options(options, AF_INET);
lease_save(self, lease, priv->lease_file);
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND,
- NM_IP_CONFIG_CAST(ip4_config),
- options);
+ l3cd);
}
static void
@@ -807,10 +793,10 @@ dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event)
break;
case N_DHCP4_CLIENT_EVENT_RETRACTED:
case N_DHCP4_CLIENT_EVENT_EXPIRED:
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_EXPIRE, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_EXPIRE, NULL);
break;
case N_DHCP4_CLIENT_EVENT_CANCELLED:
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
break;
case N_DHCP4_CLIENT_EVENT_GRANTED:
priv->lease = n_dhcp4_client_lease_ref(event->granted.lease);
@@ -862,13 +848,12 @@ dhcp4_event_cb(int fd, GIOCondition condition, gpointer user_data)
*/
_LOGE("error %d dispatching events", r);
nm_clear_g_source_inst(&priv->event_source);
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return G_SOURCE_REMOVE;
}
- while (!n_dhcp4_client_pop_event(priv->client, &event) && event) {
+ while (!n_dhcp4_client_pop_event(priv->client, &event) && event)
dhcp4_event_handle(self, event);
- }
return G_SOURCE_CONTINUE;
}
@@ -1007,7 +992,7 @@ decline(NMDhcpClient *client, const char *error_message, GError **error)
g_return_val_if_fail(priv->lease, FALSE);
- _LOGT("dhcp4-client: decline");
+ _LOGT("dhcp4-client: decline (%s)", error_message);
r = n_dhcp4_client_lease_decline(priv->lease, error_message);
if (r) {
diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c
index c789aaee0f..01184f0442 100644
--- a/src/core/dhcp/nm-dhcp-systemd.c
+++ b/src/core/dhcp/nm-dhcp-systemd.c
@@ -17,6 +17,7 @@
#include "libnm-std-aux/unaligned.h"
#include "nm-utils.h"
+#include "nm-l3-config-data.h"
#include "nm-dhcp-utils.h"
#include "nm-dhcp-options.h"
#include "nm-core-utils.h"
@@ -70,18 +71,15 @@ G_DEFINE_TYPE(NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT)
/*****************************************************************************/
-static NMIP4Config *
+static NML3ConfigData *
lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
const char * iface,
int ifindex,
sd_dhcp_lease * lease,
- guint32 route_table,
- guint32 route_metric,
- GHashTable ** out_options,
GError ** error)
{
- gs_unref_object NMIP4Config *ip4_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
const struct in_addr * addr_list;
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
const char * s;
@@ -92,7 +90,6 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
int i, num;
const void * data;
gsize data_len;
- gboolean metered = FALSE;
gboolean has_router_from_classless = FALSE;
gboolean has_classless_route = FALSE;
gboolean has_static_route = FALSE;
@@ -133,9 +130,11 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
return NULL;
}
- ip4_config = nm_ip4_config_new(multi_idx, ifindex);
+ l3cd = nm_l3_config_data_new(multi_idx, ifindex);
- options = out_options ? nm_dhcp_option_create_options_dict() : NULL;
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_DHCP);
+
+ options = nm_dhcp_option_create_options_dict();
_nm_utils_inet4_ntop(a_address.s_addr, addr_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, addr_str);
@@ -160,16 +159,16 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, addr_str);
}
- nm_ip4_config_add_address(ip4_config,
- &((const NMPlatformIP4Address){
- .address = a_address.s_addr,
- .peer_address = a_address.s_addr,
- .plen = a_plen,
- .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
- .timestamp = ts,
- .lifetime = a_lifetime,
- .preferred = a_lifetime,
- }));
+ nm_l3_config_data_add_address_4(l3cd,
+ &((const NMPlatformIP4Address){
+ .address = a_address.s_addr,
+ .peer_address = a_address.s_addr,
+ .plen = a_plen,
+ .addr_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .timestamp = ts,
+ .lifetime = a_lifetime,
+ .preferred = a_lifetime,
+ }));
if (sd_dhcp_lease_get_server_identifier(lease, &server_id) >= 0) {
_nm_utils_inet4_ntop(server_id.s_addr, addr_str);
@@ -193,7 +192,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
* See https://github.com/systemd/systemd/issues/4524. */
continue;
}
- nm_ip4_config_add_nameserver(ip4_config, addr_list[i].s_addr);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET, &addr_list[i].s_addr);
}
nm_dhcp_option_add_option(options,
AF_INET,
@@ -206,7 +205,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
g_string_append(nm_gstring_add_space_delimiter(str), search_domains[i]);
- nm_ip4_config_add_search(ip4_config, search_domains[i]);
+ nm_l3_config_data_add_search(l3cd, AF_INET, search_domains[i]);
}
nm_dhcp_option_add_option(options,
AF_INET,
@@ -224,7 +223,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
* As systemd escapes such characters, split them at \\032. */
domains = g_strsplit(s, "\\032", 0);
for (d = domains; *d; d++)
- nm_ip4_config_add_domain(ip4_config, *d);
+ nm_l3_config_data_add_domain(l3cd, AF_INET, *d);
}
if (sd_dhcp_lease_get_hostname(lease, &s) >= 0) {
@@ -233,9 +232,9 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
num = sd_dhcp_lease_get_routes(lease, &routes);
if (num > 0) {
- nm_auto_free_gstring GString *str_classless = NULL;
- nm_auto_free_gstring GString *str_static = NULL;
- guint32 default_route_metric = route_metric;
+ nm_auto_free_gstring GString *str_classless = NULL;
+ nm_auto_free_gstring GString *str_static = NULL;
+ guint32 default_route_metric_offset = 0;
for (i = 0; i < num; i++) {
switch (sd_dhcp_route_get_option(routes[i])) {
@@ -307,25 +306,22 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
if (r_plen == 0) {
/* if there are multiple default routes, we add them with differing
* metrics. */
- m = default_route_metric;
- if (default_route_metric < G_MAXUINT32)
- default_route_metric++;
-
+ m = default_route_metric_offset++;
has_router_from_classless = TRUE;
} else
- m = route_metric;
-
- nm_ip4_config_add_route(
- ip4_config,
- &((const NMPlatformIP4Route){
- .network = network_net,
- .plen = r_plen,
- .gateway = r_gateway.s_addr,
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .metric = m,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- }),
- NULL);
+ m = 0;
+
+ nm_l3_config_data_add_route_4(l3cd,
+ &((const NMPlatformIP4Route){
+ .network = network_net,
+ .plen = r_plen,
+ .gateway = r_gateway.s_addr,
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .metric_any = TRUE,
+ .metric = m,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ }));
}
if (str_classless && str_classless->len > 0)
@@ -342,7 +338,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
num = sd_dhcp_lease_get_router(lease, &a_router);
if (num > 0) {
- guint32 default_route_metric = route_metric;
+ guint32 default_route_metric_offset = 0;
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
@@ -368,26 +364,24 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
/* if there are multiple default routes, we add them with differing
* metrics. */
- m = default_route_metric;
- if (default_route_metric < G_MAXUINT32)
- default_route_metric++;
-
- nm_ip4_config_add_route(
- ip4_config,
- &((const NMPlatformIP4Route){
- .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
- .gateway = a_router[i].s_addr,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = m,
- }),
- NULL);
+ m = default_route_metric_offset++;
+
+ nm_l3_config_data_add_route_4(l3cd,
+ &((const NMPlatformIP4Route){
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .gateway = a_router[i].s_addr,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = m,
+ }));
}
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_ROUTER, str->str);
}
if (sd_dhcp_lease_get_mtu(lease, &mtu) >= 0 && mtu) {
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, mtu);
- nm_ip4_config_set_mtu(ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP);
+ nm_l3_config_data_set_mtu(l3cd, mtu);
}
num = sd_dhcp_lease_get_ntp(lease, &addr_list);
@@ -422,9 +416,10 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE, s);
}
- if (sd_dhcp_lease_get_vendor_specific(lease, &data, &data_len) >= 0)
- metered = !!memmem(data, data_len, "ANDROID_METERED", NM_STRLEN("ANDROID_METERED"));
- nm_ip4_config_set_metered(ip4_config, metered);
+ if (sd_dhcp_lease_get_vendor_specific(lease, &data, &data_len) >= 0) {
+ if (!!memmem(data, data_len, "ANDROID_METERED", NM_STRLEN("ANDROID_METERED")))
+ nm_l3_config_data_set_metered(l3cd, TRUE);
+ }
num = nm_sd_dhcp_lease_get_private_options(lease, &private_options);
if (num > 0) {
@@ -436,12 +431,18 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
if (code == NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY) {
if (nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) {
- nm_dhcp_option_add_option_utf8safe_escape(
- options,
- AF_INET,
- NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
- l_data,
- l_data_len);
+ gs_free char *to_free = NULL;
+ const char * escaped;
+
+ escaped =
+ nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
+ nm_dhcp_option_add_option(options,
+ AF_INET,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
+ escaped ?: "");
+
+ nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO);
+ nm_l3_config_data_set_proxy_pac_url(l3cd, escaped ?: "");
}
continue;
}
@@ -458,8 +459,12 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_dhcp_option_take_option(options, AF_INET, code, option_string);
}
}
- NM_SET_OUT(out_options, g_steal_pointer(&options));
- return g_steal_pointer(&ip4_config);
+
+ nm_dhcp_option_add_requests_to_options(options, AF_INET);
+
+ nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET, g_steal_pointer(&options));
+
+ return g_steal_pointer(&l3cd);
}
/*****************************************************************************/
@@ -467,43 +472,38 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
static void
bound4_handle(NMDhcpSystemd *self, gboolean extended)
{
- NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
- const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
- gs_unref_object NMIP4Config *ip4_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
- sd_dhcp_lease * lease = NULL;
- GError * error = NULL;
+ NMDhcpSystemdPrivate * priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
+ const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
+ sd_dhcp_lease * lease = NULL;
+ GError * error = NULL;
if (sd_dhcp_client_get_lease(priv->client4, &lease) < 0 || !lease) {
_LOGW("no lease!");
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
_LOGD("lease available");
- ip4_config = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
- iface,
- nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
- lease,
- nm_dhcp_client_get_route_table(NM_DHCP_CLIENT(self)),
- nm_dhcp_client_get_route_metric(NM_DHCP_CLIENT(self)),
- &options,
- &error);
- if (!ip4_config) {
+ l3cd = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
+ iface,
+ nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
+ lease,
+ &error);
+ if (!l3cd) {
_LOGW("%s", error->message);
g_clear_error(&error);
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
- nm_dhcp_option_add_requests_to_options(options, AF_INET);
dhcp_lease_save(lease, priv->lease_file);
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND,
- NM_IP_CONFIG_CAST(ip4_config),
- options);
+ l3cd);
}
static int
@@ -522,10 +522,10 @@ dhcp_event_cb(sd_dhcp_client *client, int event, gpointer user_data)
switch (event) {
case SD_DHCP_CLIENT_EVENT_EXPIRED:
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_EXPIRE, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_EXPIRE, NULL);
break;
case SD_DHCP_CLIENT_EVENT_STOP:
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_FAIL, NULL);
break;
case SD_DHCP_CLIENT_EVENT_RENEW:
case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
@@ -759,32 +759,34 @@ ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error)
return TRUE;
}
-static NMIP6Config *
+static NML3ConfigData *
lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
const char * iface,
int ifindex,
sd_dhcp6_lease * lease,
gboolean info_only,
- GHashTable ** out_options,
gint32 ts,
GError ** error)
{
- gs_unref_object NMIP6Config *ip6_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
struct in6_addr tmp_addr;
const struct in6_addr * dns;
uint32_t lft_pref, lft_valid;
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
char ** domains;
const char * s;
- nm_auto_free_gstring GString *str = NULL;
+ nm_auto_free_gstring GString *str = NULL;
+ gboolean has_any_addresses = FALSE;
int num, i;
nm_assert(lease);
- ip6_config = nm_ip6_config_new(multi_idx, ifindex);
+ l3cd = nm_l3_config_data_new(multi_idx, ifindex);
- options = out_options ? nm_dhcp_option_create_options_dict() : NULL;
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_DHCP);
+
+ options = nm_dhcp_option_create_options_dict();
sd_dhcp6_lease_reset_address_iter(lease);
nm_gstring_prepare(&str);
@@ -798,15 +800,19 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
.addr_source = NM_IP_CONFIG_SOURCE_DHCP,
};
- nm_ip6_config_add_address(ip6_config, &address);
+ nm_l3_config_data_add_address_6(l3cd, &address);
_nm_utils_inet6_ntop(&tmp_addr, addr_str);
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
- };
- if (str->len)
+
+ has_any_addresses = TRUE;
+ }
+
+ if (str->len) {
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS, str->str);
+ }
- if (!info_only && nm_ip6_config_get_num_addresses(ip6_config) == 0) {
+ if (!info_only && !has_any_addresses) {
g_set_error_literal(error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
@@ -820,7 +826,7 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
for (i = 0; i < num; i++) {
_nm_utils_inet6_ntop(&dns[i], addr_str);
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
- nm_ip6_config_add_nameserver(ip6_config, &dns[i]);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET6, &dns[i]);
}
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DNS_SERVERS, str->str);
}
@@ -830,7 +836,7 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
g_string_append(nm_gstring_add_space_delimiter(str), domains[i]);
- nm_ip6_config_add_search(ip6_config, domains[i]);
+ nm_l3_config_data_add_search(l3cd, AF_INET6, domains[i]);
}
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, str->str);
}
@@ -839,51 +845,46 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s);
}
- NM_SET_OUT(out_options, g_steal_pointer(&options));
- return g_steal_pointer(&ip6_config);
+ nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET6, g_steal_pointer(&options));
+
+ return g_steal_pointer(&l3cd);
}
static void
bound6_handle(NMDhcpSystemd *self)
{
- NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
- const gint32 ts = nm_utils_get_monotonic_timestamp_sec();
- const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
- gs_unref_object NMIP6Config *ip6_config = NULL;
- gs_unref_hashtable GHashTable *options = NULL;
- gs_free_error GError *error = NULL;
- NMPlatformIP6Address prefix = {0};
- sd_dhcp6_lease * lease = NULL;
+ NMDhcpSystemdPrivate * priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
+ const gint32 ts = nm_utils_get_monotonic_timestamp_sec();
+ const char * iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ gs_free_error GError *error = NULL;
+ NMPlatformIP6Address prefix = {0};
+ sd_dhcp6_lease * lease = NULL;
if (sd_dhcp6_client_get_lease(priv->client6, &lease) < 0 || !lease) {
_LOGW(" no lease!");
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
_LOGD("lease available");
- ip6_config =
- lease_to_ip6_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
- iface,
- nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
- lease,
- NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)),
- NM_DHCP_CLIENT_FLAGS_INFO_ONLY),
- &options,
- ts,
- &error);
-
- if (!ip6_config) {
+ l3cd = lease_to_ip6_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
+ iface,
+ nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
+ lease,
+ NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)),
+ NM_DHCP_CLIENT_FLAGS_INFO_ONLY),
+ ts,
+ &error);
+
+ if (!l3cd) {
_LOGW("%s", error->message);
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
- NM_DHCP_STATE_BOUND,
- NM_IP_CONFIG_CAST(ip6_config),
- options);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_BOUND, l3cd);
sd_dhcp6_lease_reset_pd_prefix_iter(lease);
while (!sd_dhcp6_lease_get_pd(lease,
@@ -908,11 +909,11 @@ dhcp6_event_cb(sd_dhcp6_client *client, int event, gpointer user_data)
switch (event) {
case SD_DHCP6_CLIENT_EVENT_RETRANS_MAX:
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_TIMEOUT, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_TIMEOUT, NULL);
break;
case SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE:
case SD_DHCP6_CLIENT_EVENT_STOP:
- nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
+ nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_FAIL, NULL);
break;
case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST:
diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c
index 7fd18b0a72..379baae25a 100644
--- a/src/core/dhcp/nm-dhcp-utils.c
+++ b/src/core/dhcp/nm-dhcp-utils.c
@@ -14,6 +14,7 @@
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
#include "nm-dhcp-utils.h"
+#include "nm-l3-config-data.h"
#include "nm-utils.h"
#include "nm-config.h"
#include "NetworkManagerUtils.h"
@@ -24,12 +25,10 @@
/*****************************************************************************/
static gboolean
-ip4_process_dhcpcd_rfc3442_routes(const char * iface,
- const char * str,
- guint32 route_table,
- guint32 route_metric,
- NMIP4Config *ip4_config,
- guint32 * gwaddr)
+ip4_process_dhcpcd_rfc3442_routes(const char * iface,
+ const char * str,
+ NML3ConfigData *l3cd,
+ guint32 * gwaddr)
{
gs_free const char **routes = NULL;
const char ** r;
@@ -45,10 +44,9 @@ ip4_process_dhcpcd_rfc3442_routes(const char * iface,
}
for (r = routes; *r; r += 2) {
- char * slash;
- NMPlatformIP4Route route;
- int rt_cidr = 32;
- guint32 rt_addr, rt_route;
+ char * slash;
+ int rt_cidr = 32;
+ guint32 rt_addr, rt_route;
slash = strchr(*r, '/');
if (slash) {
@@ -89,14 +87,18 @@ ip4_process_dhcpcd_rfc3442_routes(const char * iface,
*r,
rt_cidr,
*(r + 1));
- memset(&route, 0, sizeof(route));
- route.network = nm_utils_ip4_address_clear_host_address(rt_addr, rt_cidr);
- route.plen = rt_cidr;
- route.gateway = rt_route;
- route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
- route.metric = route_metric;
- route.table_coerced = nm_platform_route_table_coerce(route_table);
- nm_ip4_config_add_route(ip4_config, &route, NULL);
+
+ nm_l3_config_data_add_route_4(
+ l3cd,
+ &((const NMPlatformIP4Route){
+ .network = nm_utils_ip4_address_clear_host_address(rt_addr, rt_cidr),
+ .plen = rt_cidr,
+ .gateway = rt_route,
+ .rt_source = NM_IP_CONFIG_SOURCE_DHCP,
+ .metric_any = TRUE,
+ .table_any = TRUE,
+
+ }));
}
}
@@ -153,12 +155,10 @@ process_dhclient_rfc3442_route(const char *const **p_octets, NMPlatformIP4Route
}
static gboolean
-ip4_process_dhclient_rfc3442_routes(const char * iface,
- const char * str,
- guint32 route_table,
- guint32 route_metric,
- NMIP4Config *ip4_config,
- guint32 * gwaddr)
+ip4_process_dhclient_rfc3442_routes(const char * iface,
+ const char * str,
+ NML3ConfigData *l3cd,
+ guint32 * gwaddr)
{
gs_free const char **octets = NULL;
const char *const * o;
@@ -189,9 +189,12 @@ ip4_process_dhclient_rfc3442_routes(const char * iface,
/* normal route */
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
- route.metric = route_metric;
- route.table_coerced = nm_platform_route_table_coerce(route_table);
- nm_ip4_config_add_route(ip4_config, &route, NULL);
+ route.table_any = TRUE;
+ route.table_coerced = 0;
+ route.metric_any = TRUE;
+ route.metric = 0;
+
+ nm_l3_config_data_add_route_4(l3cd, &route);
_LOG2I(LOGD_DHCP4,
iface,
@@ -206,17 +209,15 @@ ip4_process_dhclient_rfc3442_routes(const char * iface,
}
static gboolean
-ip4_process_classless_routes(const char * iface,
- GHashTable * options,
- guint32 route_table,
- guint32 route_metric,
- NMIP4Config *ip4_config,
- guint32 * gwaddr)
+ip4_process_classless_routes(const char * iface,
+ GHashTable * options,
+ NML3ConfigData *l3cd,
+ guint32 * gwaddr)
{
const char *str, *p;
g_return_val_if_fail(options != NULL, FALSE);
- g_return_val_if_fail(ip4_config != NULL, FALSE);
+ g_return_val_if_fail(l3cd != NULL, FALSE);
*gwaddr = 0;
@@ -265,28 +266,14 @@ ip4_process_classless_routes(const char * iface,
if (strchr(str, '/')) {
/* dhcpcd format */
- return ip4_process_dhcpcd_rfc3442_routes(iface,
- str,
- route_table,
- route_metric,
- ip4_config,
- gwaddr);
+ return ip4_process_dhcpcd_rfc3442_routes(iface, str, l3cd, gwaddr);
}
- return ip4_process_dhclient_rfc3442_routes(iface,
- str,
- route_table,
- route_metric,
- ip4_config,
- gwaddr);
+ return ip4_process_dhclient_rfc3442_routes(iface, str, l3cd, gwaddr);
}
static void
-process_classful_routes(const char * iface,
- GHashTable * options,
- guint32 route_table,
- guint32 route_metric,
- NMIP4Config *ip4_config)
+process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData *l3cd)
{
gs_free const char **searches = NULL;
const char ** s;
@@ -320,8 +307,10 @@ process_classful_routes(const char * iface,
// FIXME: ensure the IP address and route are sane
- memset(&route, 0, sizeof(route));
- route.network = rt_addr;
+ route = (NMPlatformIP4Route){
+ .network = rt_addr,
+ };
+
/* RFC 2132, updated by RFC 3442:
* The Static Routes option (option 33) does not provide a subnet mask
* for each route - it is assumed that the subnet mask is implicit in
@@ -333,12 +322,15 @@ process_classful_routes(const char * iface,
}
route.gateway = rt_route;
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
- route.metric = route_metric;
- route.table_coerced = nm_platform_route_table_coerce(route_table);
+ route.table_any = TRUE;
+ route.table_coerced = 0;
+ route.metric_any = TRUE;
+ route.metric = 0;
route.network = nm_utils_ip4_address_clear_host_address(route.network, route.plen);
- nm_ip4_config_add_route(ip4_config, &route, NULL);
+ nm_l3_config_data_add_route_4(l3cd, &route);
+
_LOG2I(LOGD_DHCP,
iface,
" static route %s",
@@ -347,7 +339,7 @@ process_classful_routes(const char * iface,
}
static void
-process_domain_search(const char *iface, const char *str, GFunc add_func, gpointer user_data)
+process_domain_search(int addr_family, const char *iface, const char *str, NML3ConfigData *l3cd)
{
gs_free const char **searches = NULL;
gs_free char * unescaped = NULL;
@@ -356,7 +348,7 @@ process_domain_search(const char *iface, const char *str, GFunc add_func, gpoint
int i;
g_return_if_fail(str != NULL);
- g_return_if_fail(add_func != NULL);
+ nm_assert(l3cd);
unescaped = g_strdup(str);
@@ -379,46 +371,44 @@ process_domain_search(const char *iface, const char *str, GFunc add_func, gpoint
searches = nm_utils_strsplit_set(unescaped, " ");
for (s = searches; searches && *s; s++) {
_LOG2I(LOGD_DHCP, iface, " domain search '%s'", *s);
- add_func((gpointer) *s, user_data);
+ nm_l3_config_data_add_search(l3cd, addr_family, *s);
}
}
-static void
-ip4_add_domain_search(gpointer data, gpointer user_data)
-{
- nm_ip4_config_add_search(NM_IP4_CONFIG(user_data), (const char *) data);
-}
-
-NMIP4Config *
+NML3ConfigData *
nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
int ifindex,
const char * iface,
- GHashTable * options,
- guint32 route_table,
- guint32 route_metric)
+ GHashTable * options)
{
- gs_unref_object NMIP4Config *ip4_config = NULL;
- guint32 tmp_addr;
- in_addr_t addr;
- NMPlatformIP4Address address;
- char * str = NULL;
- gboolean gateway_has = FALSE;
- guint32 gateway = 0;
- guint8 plen = 0;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ guint32 tmp_addr;
+ in_addr_t addr;
+ NMPlatformIP4Address address;
+ char * str = NULL;
+ gboolean gateway_has = FALSE;
+ guint32 gateway = 0;
+ guint8 plen = 0;
+ char sbuf[NM_UTILS_INET_ADDRSTRLEN];
+ guint32 now;
g_return_val_if_fail(options != NULL, NULL);
- ip4_config = nm_ip4_config_new(multi_idx, ifindex);
- memset(&address, 0, sizeof(address));
- address.timestamp = nm_utils_get_monotonic_timestamp_sec();
+ l3cd = nm_l3_config_data_new(multi_idx, ifindex);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_DHCP);
+
+ now = nm_utils_get_monotonic_timestamp_sec();
+
+ address = (NMPlatformIP4Address){
+ .timestamp = now,
+ };
str = g_hash_table_lookup(options, "ip_address");
- if (str && (inet_pton(AF_INET, str, &addr) > 0))
- _LOG2I(LOGD_DHCP4, iface, " address %s", str);
- else
+ if (!str || !nm_utils_parse_inaddr_bin(AF_INET, str, NULL, &addr))
return NULL;
+ _LOG2I(LOGD_DHCP4, iface, " address %s", str);
+
str = g_hash_table_lookup(options, "subnet_mask");
if (str && (inet_pton(AF_INET, str, &tmp_addr) > 0)) {
plen = nm_utils_ip4_netmask_to_prefix(tmp_addr);
@@ -433,13 +423,8 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
/* Routes: if the server returns classless static routes, we MUST ignore
* the 'static_routes' option.
*/
- if (!ip4_process_classless_routes(iface,
- options,
- route_table,
- route_metric,
- ip4_config,
- &gateway))
- process_classful_routes(iface, options, route_table, route_metric, ip4_config);
+ if (!ip4_process_classless_routes(iface, options, l3cd, &gateway))
+ process_classful_routes(iface, options, l3cd);
if (gateway) {
_LOG2I(LOGD_DHCP4, iface, " gateway %s", _nm_utils_inet4_ntop(gateway, sbuf));
@@ -450,10 +435,10 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
*/
str = g_hash_table_lookup(options, "routers");
if (str) {
- gs_free const char **routers = nm_utils_strsplit_set(str, " ");
- const char ** s;
+ char **routers = g_strsplit(str, " ", 0);
+ char **s;
- for (s = routers; routers && *s; s++) {
+ for (s = routers; *s; s++) {
/* FIXME: how to handle multiple routers? */
if (inet_pton(AF_INET, *s, &gateway) > 0) {
_LOG2I(LOGD_DHCP4, iface, " gateway %s", *s);
@@ -462,6 +447,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
} else
_LOG2W(LOGD_DHCP4, iface, "ignoring invalid gateway '%s'", *s);
}
+ g_strfreev(routers);
}
}
@@ -469,11 +455,13 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
const NMPlatformIP4Route r = {
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
.gateway = gateway,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
- nm_ip4_config_add_route(ip4_config, &r, NULL);
+ nm_l3_config_data_add_route_4(l3cd, &r);
}
str = g_hash_table_lookup(options, "dhcp_lease_time");
@@ -483,7 +471,8 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
}
address.addr_source = NM_IP_CONFIG_SOURCE_DHCP;
- nm_ip4_config_add_address(ip4_config, &address);
+
+ nm_l3_config_data_add_address_4(l3cd, &address);
str = g_hash_table_lookup(options, "host_name");
if (str)
@@ -497,7 +486,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
for (s = dns; dns && *s; s++) {
if (inet_pton(AF_INET, *s, &tmp_addr) > 0) {
if (tmp_addr) {
- nm_ip4_config_add_nameserver(ip4_config, tmp_addr);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET, &tmp_addr);
_LOG2I(LOGD_DHCP4, iface, " nameserver '%s'", *s);
}
} else
@@ -512,13 +501,13 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
for (s = domains; domains && *s; s++) {
_LOG2I(LOGD_DHCP4, iface, " domain name '%s'", *s);
- nm_ip4_config_add_domain(ip4_config, *s);
+ nm_l3_config_data_add_domain(l3cd, AF_INET, *s);
}
}
str = g_hash_table_lookup(options, "domain_search");
if (str)
- process_domain_search(iface, str, ip4_add_domain_search, ip4_config);
+ process_domain_search(AF_INET, iface, str, l3cd);
str = g_hash_table_lookup(options, "netbios_name_servers");
if (str) {
@@ -528,7 +517,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
for (s = nbns; nbns && *s; s++) {
if (inet_pton(AF_INET, *s, &tmp_addr) > 0) {
if (tmp_addr) {
- nm_ip4_config_add_wins(ip4_config, tmp_addr);
+ nm_l3_config_data_add_wins(l3cd, tmp_addr);
_LOG2I(LOGD_DHCP4, iface, " wins '%s'", *s);
}
} else
@@ -546,13 +535,13 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
return NULL;
if (int_mtu > 576)
- nm_ip4_config_set_mtu(ip4_config, int_mtu, NM_IP_CONFIG_SOURCE_DHCP);
+ nm_l3_config_data_set_mtu(l3cd, int_mtu);
}
str = g_hash_table_lookup(options, "nis_domain");
if (str) {
_LOG2I(LOGD_DHCP4, iface, " NIS domain '%s'", str);
- nm_ip4_config_set_nis_domain(ip4_config, str);
+ nm_l3_config_data_add_domain(l3cd, AF_INET, str);
}
str = g_hash_table_lookup(options, "nis_servers");
@@ -563,7 +552,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
for (s = nis; nis && *s; s++) {
if (inet_pton(AF_INET, *s, &tmp_addr) > 0) {
if (tmp_addr) {
- nm_ip4_config_add_nis_server(ip4_config, tmp_addr);
+ nm_l3_config_data_add_nis_server(l3cd, tmp_addr);
_LOG2I(LOGD_DHCP4, iface, " nis '%s'", *s);
}
} else
@@ -572,19 +561,20 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
}
str = g_hash_table_lookup(options, "vendor_encapsulated_options");
- nm_ip4_config_set_metered(ip4_config, str && strstr(str, "ANDROID_METERED"));
+ if (str && strstr(str, "ANDROID_METERED"))
+ nm_l3_config_data_set_metered(l3cd, TRUE);
- return g_steal_pointer(&ip4_config);
+ str = g_hash_table_lookup(options, "wpad");
+ if (str) {
+ nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO);
+ nm_l3_config_data_set_proxy_pac_url(l3cd, str);
+ }
+
+ return g_steal_pointer(&l3cd);
}
/*****************************************************************************/
-static void
-ip6_add_domain_search(gpointer data, gpointer user_data)
-{
- nm_ip6_config_add_search(NM_IP6_CONFIG(user_data), (const char *) data);
-}
-
NMPlatformIP6Address
nm_dhcp_utils_ip6_prefix_from_options(GHashTable *options)
{
@@ -635,25 +625,30 @@ nm_dhcp_utils_ip6_prefix_from_options(GHashTable *options)
return address;
}
-NMIP6Config *
+NML3ConfigData *
nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx,
int ifindex,
const char * iface,
GHashTable * options,
gboolean info_only)
{
- gs_unref_object NMIP6Config *ip6_config = NULL;
- struct in6_addr tmp_addr;
- NMPlatformIP6Address address;
- char * str = NULL;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ struct in6_addr tmp_addr;
+ NMPlatformIP6Address address;
+ char * str = NULL;
+ guint32 now;
g_return_val_if_fail(options != NULL, NULL);
- memset(&address, 0, sizeof(address));
- address.plen = 128;
- address.timestamp = nm_utils_get_monotonic_timestamp_sec();
+ now = nm_utils_get_monotonic_timestamp_sec();
- ip6_config = nm_ip6_config_new(multi_idx, ifindex);
+ address = (NMPlatformIP6Address){
+ .plen = 128,
+ .timestamp = now,
+ };
+
+ l3cd = nm_l3_config_data_new(multi_idx, ifindex);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_DHCP);
str = g_hash_table_lookup(options, "max_life");
if (str) {
@@ -676,7 +671,7 @@ nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx,
address.address = tmp_addr;
address.addr_source = NM_IP_CONFIG_SOURCE_DHCP;
- nm_ip6_config_add_address(ip6_config, &address);
+ nm_l3_config_data_add_address_6(l3cd, &address);
_LOG2I(LOGD_DHCP6, iface, " address %s", str);
} else if (info_only == FALSE) {
/* No address in Managed mode is a hard error */
@@ -695,7 +690,7 @@ nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx,
for (s = dns; dns && *s; s++) {
if (inet_pton(AF_INET6, *s, &tmp_addr) > 0) {
if (!IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
- nm_ip6_config_add_nameserver(ip6_config, &tmp_addr);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET6, &tmp_addr);
_LOG2I(LOGD_DHCP6, iface, " nameserver '%s'", *s);
}
} else
@@ -705,9 +700,9 @@ nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx,
str = g_hash_table_lookup(options, "dhcp6_domain_search");
if (str)
- process_domain_search(iface, str, ip6_add_domain_search, ip6_config);
+ process_domain_search(AF_INET6, iface, str, l3cd);
- return g_steal_pointer(&ip6_config);
+ return g_steal_pointer(&l3cd);
}
char *
@@ -838,6 +833,65 @@ nm_dhcp_utils_get_dhcp6_event_id(GHashTable *lease)
return g_strdup_printf("%s|%s", iaid, start);
}
+gboolean
+nm_dhcp_utils_merge_new_dhcp6_lease(const NML3ConfigData * l3cd_old,
+ const NML3ConfigData * l3cd_new,
+ const NML3ConfigData **out_l3cd_merged)
+{
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd_merged = NULL;
+ const NMPlatformIP6Address * addr;
+ NMDhcpLease * lease_old;
+ NMDhcpLease * lease_new;
+ NMDedupMultiIter iter;
+ const char * start;
+ const char * iaid;
+
+ nm_assert(out_l3cd_merged);
+ nm_assert(!*out_l3cd_merged);
+
+ if (!l3cd_old)
+ return FALSE;
+ if (!l3cd_new)
+ return FALSE;
+
+ lease_new = nm_l3_config_data_get_dhcp_lease(l3cd_new, AF_INET6);
+ if (!lease_new)
+ return FALSE;
+
+ lease_old = nm_l3_config_data_get_dhcp_lease(l3cd_old, AF_INET6);
+ if (!lease_old)
+ return FALSE;
+
+ start = nm_dhcp_lease_lookup_option(lease_new, "life_starts");
+ if (!start)
+ return FALSE;
+ iaid = nm_dhcp_lease_lookup_option(lease_new, "iaid");
+ if (!iaid)
+ return FALSE;
+
+ if (!nm_streq0(start, nm_dhcp_lease_lookup_option(lease_old, "life_starts")))
+ return FALSE;
+ if (!nm_streq0(iaid, nm_dhcp_lease_lookup_option(lease_old, "iaid")))
+ return FALSE;
+
+ /* If the server sends multiple IPv6 addresses, we receive a state
+ * changed event for each of them. Use the event ID to merge IPv6
+ * addresses from the same transaction into a single configuration.
+ **/
+
+ l3cd_merged = nm_l3_config_data_new_clone(l3cd_old, -1);
+
+ nm_l3_config_data_iter_ip6_address_for_each (&iter, l3cd_new, &addr)
+ nm_l3_config_data_add_address_6(l3cd_merged, addr);
+
+ /* Note that we keep the original NMDhcpLease. All we take from the new lease are the
+ * addresses. Maybe this is not right?? */
+ nm_l3_config_data_set_dhcp_lease(l3cd_merged, AF_INET6, lease_old);
+
+ *out_l3cd_merged = nm_l3_config_data_ref_and_seal(g_steal_pointer(&l3cd_merged));
+ return TRUE;
+}
+
/*****************************************************************************/
gboolean
diff --git a/src/core/dhcp/nm-dhcp-utils.h b/src/core/dhcp/nm-dhcp-utils.h
index 69715f90fe..bee10de3f6 100644
--- a/src/core/dhcp/nm-dhcp-utils.h
+++ b/src/core/dhcp/nm-dhcp-utils.h
@@ -8,21 +8,18 @@
#include <stdlib.h>
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
-
-NMIP4Config *nm_dhcp_utils_ip4_config_from_options(struct _NMDedupMultiIndex *multi_idx,
- int ifindex,
- const char * iface,
- GHashTable * options,
- guint32 route_table,
- guint32 route_metric);
-
-NMIP6Config *nm_dhcp_utils_ip6_config_from_options(struct _NMDedupMultiIndex *multi_idx,
- int ifindex,
- const char * iface,
- GHashTable * options,
- gboolean info_only);
+#include "nm-l3-config-data.h"
+
+NML3ConfigData *nm_dhcp_utils_ip4_config_from_options(struct _NMDedupMultiIndex *multi_idx,
+ int ifindex,
+ const char * iface,
+ GHashTable * options);
+
+NML3ConfigData *nm_dhcp_utils_ip6_config_from_options(struct _NMDedupMultiIndex *multi_idx,
+ int ifindex,
+ const char * iface,
+ GHashTable * options,
+ gboolean info_only);
NMPlatformIP6Address nm_dhcp_utils_ip6_prefix_from_options(GHashTable *options);
@@ -38,6 +35,10 @@ gboolean nm_dhcp_utils_get_leasefile_path(int addr_family,
char *nm_dhcp_utils_get_dhcp6_event_id(GHashTable *lease);
+gboolean nm_dhcp_utils_merge_new_dhcp6_lease(const NML3ConfigData * l3cd_old,
+ const NML3ConfigData * l3cd_new,
+ const NML3ConfigData **out_l3cd_merged);
+
/*****************************************************************************/
static inline gboolean
diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c
index e9a6209644..803933ff04 100644
--- a/src/core/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/core/dhcp/tests/test-dhcp-dhclient.c
@@ -15,7 +15,6 @@
#include "dhcp/nm-dhcp-dhclient-utils.h"
#include "dhcp/nm-dhcp-utils.h"
#include "nm-utils.h"
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-test-utils-core.h"
diff --git a/src/core/dhcp/tests/test-dhcp-utils.c b/src/core/dhcp/tests/test-dhcp-utils.c
index 4d47e7e283..0fab5c15ad 100644
--- a/src/core/dhcp/tests/test-dhcp-utils.c
+++ b/src/core/dhcp/tests/test-dhcp-utils.c
@@ -20,20 +20,18 @@
/*****************************************************************************/
-static NMIP4Config *
-_ip4_config_from_options(int ifindex, const char *iface, GHashTable *options, guint32 route_metric)
+static const NML3ConfigData *
+_ip4_config_from_options(int ifindex, const char *iface, GHashTable *options)
{
nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new();
- NMIP4Config * config;
-
- config = nm_dhcp_utils_ip4_config_from_options(multi_idx,
- ifindex,
- iface,
- options,
- RT_TABLE_MAIN,
- route_metric);
- g_assert(config);
- return config;
+ NML3ConfigData * l3cd;
+
+ l3cd = nm_dhcp_utils_ip4_config_from_options(multi_idx, ifindex, iface, options);
+ g_assert(NM_IS_L3_CONFIG_DATA(l3cd));
+ g_assert(!nm_l3_config_data_is_sealed(l3cd));
+ if (nmtst_get_rand_bool())
+ nm_l3_config_data_seal(l3cd);
+ return l3cd;
}
typedef struct {
@@ -74,58 +72,57 @@ static const Option generic_options[] = {
static void
test_generic_options(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const NMPlatformIP4Address * address;
- const NMPlatformIP4Route * route;
- guint32 tmp;
- const char * expected_addr = "192.168.1.106";
- const char * expected_gw = "192.168.1.1";
- const char * expected_dns1 = "216.254.95.2";
- const char * expected_dns2 = "216.231.41.2";
- const char * expected_search1 = "foobar.com";
- const char * expected_search2 = "blah.foobar.com";
- const char * expected_route1_dest = "10.1.1.5";
- const char * expected_route1_gw = "10.1.1.1";
- const char * expected_route2_dest = "100.99.88.56";
- const char * expected_route2_gw = "10.1.1.1";
-
- options = fill_table(generic_options, NULL);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
-
- /* IP4 address */
- g_assert_cmpint(nm_ip4_config_get_num_addresses(ip4_config), ==, 1);
- address = _nmtst_ip4_config_get_address(ip4_config, 0);
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const NMPlatformIP4Address * address;
+ const NMPlatformIP4Route * route;
+ guint32 tmp;
+ const char * expected_addr = "192.168.1.106";
+ const char * expected_gw = "192.168.1.1";
+ const char * expected_dns1 = "216.254.95.2";
+ const char * expected_dns2 = "216.231.41.2";
+ const char * expected_search1 = "foobar.com";
+ const char * expected_search2 = "blah.foobar.com";
+ const char * expected_route1_dest = "10.1.1.5";
+ const char * expected_route1_gw = "10.1.1.1";
+ const char * expected_route2_dest = "100.99.88.56";
+ const char * expected_route2_gw = "10.1.1.1";
+ const char *const * strarr;
+ const in_addr_t * ia_arr;
+ guint u;
+
+ options = fill_table(generic_options, NULL);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
+
+ g_assert_cmpint(nm_l3_config_data_get_num_addresses(l3cd, AF_INET), ==, 1);
+ address = nmtst_l3_config_data_get_address_at_4(l3cd, 0);
g_assert(inet_pton(AF_INET, expected_addr, &tmp) > 0);
g_assert(address->address == tmp);
g_assert(address->peer_address == tmp);
g_assert_cmpint(address->plen, ==, 24);
- /* Gateway */
- g_assert(inet_pton(AF_INET, expected_gw, &tmp) > 0);
- g_assert(nmtst_ip4_config_get_gateway(ip4_config) == tmp);
+ nmtst_assert_ip_address(AF_INET,
+ nmtst_l3_config_data_get_best_gateway(l3cd, AF_INET),
+ expected_gw);
- g_assert_cmpint(nm_ip4_config_get_num_wins(ip4_config), ==, 0);
+ g_assert(!nm_l3_config_data_get_wins(l3cd, &u));
+ g_assert_cmpint(u, ==, 0);
- g_assert_cmpint(nm_ip4_config_get_mtu(ip4_config), ==, 987);
+ g_assert_cmpint(nm_l3_config_data_get_mtu(l3cd), ==, 987);
- /* Domain searches */
- g_assert_cmpint(nm_ip4_config_get_num_searches(ip4_config), ==, 2);
- g_assert_cmpstr(nm_ip4_config_get_search(ip4_config, 0), ==, expected_search1);
- g_assert_cmpstr(nm_ip4_config_get_search(ip4_config, 1), ==, expected_search2);
+ strarr = nm_l3_config_data_get_searches(l3cd, AF_INET, &u);
+ g_assert_cmpint(u, ==, 2);
+ g_assert_cmpstr(strarr[0], ==, expected_search1);
+ g_assert_cmpstr(strarr[1], ==, expected_search2);
- /* DNS servers */
- g_assert_cmpint(nm_ip4_config_get_num_nameservers(ip4_config), ==, 2);
- g_assert(inet_pton(AF_INET, expected_dns1, &tmp) > 0);
- g_assert(nm_ip4_config_get_nameserver(ip4_config, 0) == tmp);
- g_assert(inet_pton(AF_INET, expected_dns2, &tmp) > 0);
- g_assert(nm_ip4_config_get_nameserver(ip4_config, 1) == tmp);
+ ia_arr = nm_l3_config_data_get_nameservers(l3cd, AF_INET, &u);
+ g_assert_cmpint(u, ==, 2);
+ nmtst_assert_ip4_address(ia_arr[0], expected_dns1);
+ nmtst_assert_ip4_address(ia_arr[1], expected_dns2);
- /* Routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
- /* Route #1 */
- route = _nmtst_ip4_config_get_route(ip4_config, 0);
+ route = nmtst_l3_config_data_get_route_at_4(l3cd, 0);
g_assert(inet_pton(AF_INET, expected_route1_dest, &tmp) > 0);
g_assert(route->network == tmp);
g_assert(inet_pton(AF_INET, expected_route1_gw, &tmp) > 0);
@@ -133,69 +130,63 @@ test_generic_options(void)
g_assert_cmpint(route->plen, ==, 32);
g_assert_cmpint(route->metric, ==, 0);
- /* Route #2 */
- route = _nmtst_ip4_config_get_route(ip4_config, 1);
+ route = nmtst_l3_config_data_get_route_at_4(l3cd, 1);
g_assert(route->network == nmtst_inet4_from_string(expected_route2_dest));
g_assert(route->gateway == nmtst_inet4_from_string(expected_route2_gw));
g_assert_cmpint(route->plen, ==, 32);
g_assert_cmpint(route->metric, ==, 0);
- route = _nmtst_ip4_config_get_route(ip4_config, 2);
+ route = nmtst_l3_config_data_get_route_at_4(l3cd, 2);
g_assert(route->network == nmtst_inet4_from_string("0.0.0.0"));
g_assert(route->gateway == nmtst_inet4_from_string("192.168.1.1"));
g_assert_cmpint(route->plen, ==, 0);
g_assert_cmpint(route->metric, ==, 0);
-
- g_hash_table_destroy(options);
}
static void
test_wins_options(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const NMPlatformIP4Address * address;
- guint32 tmp;
- const char * expected_wins1 = "63.12.199.5";
- const char * expected_wins2 = "150.4.88.120";
- static const Option data[] = {{"netbios_name_servers", "63.12.199.5 150.4.88.120"},
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const NMPlatformIP4Address * address;
+ const char * expected_wins1 = "63.12.199.5";
+ const char * expected_wins2 = "150.4.88.120";
+ static const Option data[] = {{"netbios_name_servers", "63.12.199.5 150.4.88.120"},
{NULL, NULL}};
+ const in_addr_t * ia_arr;
+ guint u;
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
- /* IP4 address */
- g_assert_cmpint(nm_ip4_config_get_num_addresses(ip4_config), ==, 1);
- address = _nmtst_ip4_config_get_address(ip4_config, 0);
+ g_assert_cmpint(nm_l3_config_data_get_num_addresses(l3cd, AF_INET), ==, 1);
+ address = nmtst_l3_config_data_get_address_at_4(l3cd, 0);
g_assert(address);
- g_assert_cmpint(nm_ip4_config_get_num_wins(ip4_config), ==, 2);
- g_assert(inet_pton(AF_INET, expected_wins1, &tmp) > 0);
- g_assert(nm_ip4_config_get_wins(ip4_config, 0) == tmp);
- g_assert(inet_pton(AF_INET, expected_wins2, &tmp) > 0);
- g_assert(nm_ip4_config_get_wins(ip4_config, 1) == tmp);
- g_hash_table_destroy(options);
+ ia_arr = nm_l3_config_data_get_wins(l3cd, &u);
+ g_assert_cmpint(u, ==, 2);
+ nmtst_assert_ip4_address(ia_arr[0], expected_wins1);
+ nmtst_assert_ip4_address(ia_arr[1], expected_wins2);
}
static void
test_vendor_option_metered(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
static const Option data[] = {{"vendor_encapsulated_options", "ANDROID_METERED"}, {NULL, NULL}};
- options = fill_table(generic_options, NULL);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
- g_assert(nm_ip4_config_get_metered(ip4_config) == FALSE);
- g_hash_table_destroy(options);
- g_clear_object(&ip4_config);
-
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
- g_assert(nm_ip4_config_get_metered(ip4_config) == TRUE);
- g_hash_table_destroy(options);
+ options = fill_table(generic_options, NULL);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
+ g_assert(nm_l3_config_data_get_metered(l3cd) == NM_TERNARY_DEFAULT);
+ nm_clear_pointer(&options, g_hash_table_destroy);
+ nm_clear_l3cd(&l3cd);
+
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
+ g_assert(nm_l3_config_data_get_metered(l3cd) == TRUE);
}
static void
@@ -252,18 +243,18 @@ test_parse_search_list(void)
}
static void
-ip4_test_route(NMIP4Config *ip4_config,
- guint route_num,
- const char * expected_dest,
- const char * expected_gw,
- guint expected_prefix)
+ip4_test_route(const NML3ConfigData *l3cd,
+ guint route_num,
+ const char * expected_dest,
+ const char * expected_gw,
+ guint expected_prefix)
{
const NMPlatformIP4Route *route;
guint32 tmp;
g_assert(expected_prefix <= 32);
- route = _nmtst_ip4_config_get_route(ip4_config, route_num);
+ route = nmtst_l3_config_data_get_route_at_4(l3cd, route_num);
g_assert(inet_pton(AF_INET, expected_dest, &tmp) > 0);
g_assert(route->network == tmp);
g_assert(inet_pton(AF_INET, expected_gw, &tmp) > 0);
@@ -272,110 +263,105 @@ ip4_test_route(NMIP4Config *ip4_config,
g_assert_cmpint(route->metric, ==, 0);
}
-static void
-ip4_test_gateway(NMIP4Config *ip4_config, const char *expected_gw)
-{
- guint32 tmp;
-
- g_assert_cmpint(nm_ip4_config_get_num_addresses(ip4_config), ==, 1);
- g_assert(inet_pton(AF_INET, expected_gw, &tmp) > 0);
- g_assert(nmtst_ip4_config_get_gateway(ip4_config) == tmp);
-}
+#define ip4_test_gateway(l3cd, expected_gw) \
+ G_STMT_START \
+ { \
+ const NML3ConfigData *_l3cd = (l3cd); \
+ \
+ g_assert_cmpint(nm_l3_config_data_get_num_addresses(_l3cd, AF_INET), ==, 1); \
+ nmtst_assert_ip_address(AF_INET, \
+ nmtst_l3_config_data_get_best_gateway(_l3cd, AF_INET), \
+ expected_gw); \
+ } \
+ G_STMT_END
static void
test_classless_static_routes_1(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- const char * expected_route2_dest = "10.0.0.0";
- const char * expected_route2_gw = "10.17.66.41";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ const char * expected_route2_dest = "10.0.0.0";
+ const char * expected_route2_gw = "10.17.66.41";
+ static const Option data[] = {
/* dhclient custom format */
{"rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41"},
{NULL, NULL}};
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, expected_route2_dest, expected_route2_gw, 8);
- ip4_test_route(ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, expected_route2_dest, expected_route2_gw, 8);
+ ip4_test_route(l3cd, 2, "0.0.0.0", "192.168.1.1", 0);
}
static void
test_classless_static_routes_2(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- const char * expected_route2_dest = "10.0.0.0";
- const char * expected_route2_gw = "10.17.66.41";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ const char * expected_route2_dest = "10.0.0.0";
+ const char * expected_route2_gw = "10.17.66.41";
+ static const Option data[] = {
/* dhcpcd format */
{"classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41"},
{NULL, NULL}};
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, expected_route2_dest, expected_route2_gw, 8);
- ip4_test_route(ip4_config, 2, "0.0.0.0", expected_route1_gw, 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, expected_route2_dest, expected_route2_gw, 8);
+ ip4_test_route(l3cd, 2, "0.0.0.0", expected_route1_gw, 0);
}
static void
test_fedora_dhclient_classless_static_routes(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "129.210.177.128";
- const char * expected_route1_gw = "192.168.0.113";
- const char * expected_route2_dest = "2.0.0.0";
- const char * expected_route2_gw = "10.34.255.6";
- const char * expected_gateway = "192.168.0.113";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "129.210.177.128";
+ const char * expected_route1_gw = "192.168.0.113";
+ const char * expected_route2_dest = "2.0.0.0";
+ const char * expected_route2_gw = "10.34.255.6";
+ const char * expected_gateway = "192.168.0.113";
+ static const Option data[] = {
/* Fedora dhclient format */
{"classless_static_routes",
"0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6"},
{NULL, NULL}};
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 25);
- ip4_test_route(ip4_config, 1, expected_route2_dest, expected_route2_gw, 7);
- ip4_test_route(ip4_config, 2, "0.0.0.0", expected_route1_gw, 0);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 25);
+ ip4_test_route(l3cd, 1, expected_route2_dest, expected_route2_gw, 7);
+ ip4_test_route(l3cd, 2, "0.0.0.0", expected_route1_gw, 0);
- /* Gateway */
- ip4_test_gateway(ip4_config, expected_gateway);
-
- g_hash_table_destroy(options);
+ ip4_test_gateway(l3cd, expected_gateway);
}
static void
test_dhclient_invalid_classless_routes_1(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ static const Option data[] = {
/* dhclient format */
{"rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41"},
{NULL, NULL}};
@@ -384,27 +370,25 @@ test_dhclient_invalid_classless_routes_1(void)
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*ignoring invalid classless static routes*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 2);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, "0.0.0.0", expected_route1_gw, 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 2);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, "0.0.0.0", expected_route1_gw, 0);
}
static void
test_dhcpcd_invalid_classless_routes_1(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "10.1.1.5";
- const char * expected_route1_gw = "10.1.1.1";
- const char * expected_route2_dest = "100.99.88.56";
- const char * expected_route2_gw = "10.1.1.1";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "10.1.1.5";
+ const char * expected_route1_gw = "10.1.1.1";
+ const char * expected_route2_dest = "100.99.88.56";
+ const char * expected_route2_gw = "10.1.1.1";
+ static const Option data[] = {
/* dhcpcd format */
{"classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41"},
{NULL, NULL}};
@@ -413,30 +397,28 @@ test_dhcpcd_invalid_classless_routes_1(void)
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*ignoring invalid classless static routes*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
- ip4_test_route(ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
- ip4_test_route(ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 32);
+ ip4_test_route(l3cd, 1, expected_route2_dest, expected_route2_gw, 32);
+ ip4_test_route(l3cd, 2, "0.0.0.0", "192.168.1.1", 0);
}
static void
test_dhclient_invalid_classless_routes_2(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "10.1.1.5";
- const char * expected_route1_gw = "10.1.1.1";
- const char * expected_route2_dest = "100.99.88.56";
- const char * expected_route2_gw = "10.1.1.1";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "10.1.1.5";
+ const char * expected_route1_gw = "10.1.1.1";
+ const char * expected_route2_dest = "100.99.88.56";
+ const char * expected_route2_gw = "10.1.1.1";
+ static const Option data[] = {
{"rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1"},
{NULL, NULL}};
@@ -444,30 +426,28 @@ test_dhclient_invalid_classless_routes_2(void)
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*ignoring invalid classless static routes*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
- ip4_test_route(ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
- ip4_test_route(ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 32);
+ ip4_test_route(l3cd, 1, expected_route2_dest, expected_route2_gw, 32);
+ ip4_test_route(l3cd, 2, "0.0.0.0", "192.168.1.1", 0);
}
static void
test_dhcpcd_invalid_classless_routes_2(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "10.1.1.5";
- const char * expected_route1_gw = "10.1.1.1";
- const char * expected_route2_dest = "100.99.88.56";
- const char * expected_route2_gw = "10.1.1.1";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "10.1.1.5";
+ const char * expected_route1_gw = "10.1.1.1";
+ const char * expected_route2_dest = "100.99.88.56";
+ const char * expected_route2_gw = "10.1.1.1";
+ static const Option data[] = {
{"classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1"},
{NULL, NULL}};
@@ -475,7 +455,7 @@ test_dhcpcd_invalid_classless_routes_2(void)
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*ignoring invalid classless static routes*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
/* Test falling back to old-style static routes if the classless static
@@ -483,22 +463,20 @@ test_dhcpcd_invalid_classless_routes_2(void)
*/
/* Routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 3);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
- ip4_test_route(ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
- ip4_test_route(ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 3);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 32);
+ ip4_test_route(l3cd, 1, expected_route2_dest, expected_route2_gw, 32);
+ ip4_test_route(l3cd, 2, "0.0.0.0", "192.168.1.1", 0);
}
static void
test_dhclient_invalid_classless_routes_3(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- static const Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ static const Option data[] = {
{"rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41"},
{NULL, NULL}};
@@ -506,25 +484,23 @@ test_dhclient_invalid_classless_routes_3(void)
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*ignoring invalid classless static routes*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 2);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, "0.0.0.0", expected_route1_gw, 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 2);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, "0.0.0.0", expected_route1_gw, 0);
}
static void
test_dhcpcd_invalid_classless_routes_3(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- static Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ static Option data[] = {
{"classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41"},
{NULL, NULL}};
@@ -532,133 +508,124 @@ test_dhcpcd_invalid_classless_routes_3(void)
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*DHCP provided invalid classless static route*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 2);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, "0.0.0.0", expected_route1_gw, 0);
-
- g_hash_table_destroy(options);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 2);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, "0.0.0.0", expected_route1_gw, 0);
}
static void
test_dhclient_gw_in_classless_routes(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- const char * expected_gateway = "192.2.3.4";
- static Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ const char * expected_gateway = "192.2.3.4";
+ static Option data[] = {
{"rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4"},
{NULL, NULL}};
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 2);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, "0.0.0.0", "192.2.3.4", 0);
-
- /* Gateway */
- ip4_test_gateway(ip4_config, expected_gateway);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 2);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, "0.0.0.0", "192.2.3.4", 0);
- g_hash_table_destroy(options);
+ ip4_test_gateway(l3cd, expected_gateway);
}
static void
test_dhcpcd_gw_in_classless_routes(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_route1_dest = "192.168.10.0";
- const char * expected_route1_gw = "192.168.1.1";
- const char * expected_gateway = "192.2.3.4";
- static Option data[] = {
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_route1_dest = "192.168.10.0";
+ const char * expected_route1_gw = "192.168.1.1";
+ const char * expected_gateway = "192.2.3.4";
+ static Option data[] = {
{"classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4"},
{NULL, NULL}};
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
/* IP4 routes */
- g_assert_cmpint(nm_ip4_config_get_num_routes(ip4_config), ==, 2);
- ip4_test_route(ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
- ip4_test_route(ip4_config, 1, "0.0.0.0", "192.2.3.4", 0);
-
- /* Gateway */
- ip4_test_gateway(ip4_config, expected_gateway);
+ g_assert_cmpint(nm_l3_config_data_get_num_routes(l3cd, AF_INET), ==, 2);
+ ip4_test_route(l3cd, 0, expected_route1_dest, expected_route1_gw, 24);
+ ip4_test_route(l3cd, 1, "0.0.0.0", "192.2.3.4", 0);
- g_hash_table_destroy(options);
+ ip4_test_gateway(l3cd, expected_gateway);
}
static void
test_escaped_domain_searches(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const char * expected_search0 = "host1";
- const char * expected_search1 = "host2";
- const char * expected_search2 = "host3";
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const char * expected_search0 = "host1";
+ const char * expected_search1 = "host2";
+ const char * expected_search2 = "host3";
static const Option data[] = {{"domain_search", "host1\\032host2\\032host3"}, {NULL, NULL}};
+ const char *const * strarr;
+ guint u;
- options = fill_table(generic_options, NULL);
- options = fill_table(data, options);
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
-
- /* domain searches */
- g_assert_cmpint(nm_ip4_config_get_num_searches(ip4_config), ==, 3);
- g_assert_cmpstr(nm_ip4_config_get_search(ip4_config, 0), ==, expected_search0);
- g_assert_cmpstr(nm_ip4_config_get_search(ip4_config, 1), ==, expected_search1);
- g_assert_cmpstr(nm_ip4_config_get_search(ip4_config, 2), ==, expected_search2);
+ options = fill_table(generic_options, NULL);
+ options = fill_table(data, options);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
- g_hash_table_destroy(options);
+ strarr = nm_l3_config_data_get_searches(l3cd, AF_INET, &u);
+ g_assert_cmpint(u, ==, 3);
+ g_assert_cmpstr(strarr[0], ==, expected_search0);
+ g_assert_cmpstr(strarr[1], ==, expected_search1);
+ g_assert_cmpstr(strarr[2], ==, expected_search2);
}
static void
test_invalid_escaped_domain_searches(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
static const Option data[] = {{"domain_search", "host1\\aahost2\\032host3"}, {NULL, NULL}};
+ const char *const * strarr;
+ guint u;
options = fill_table(generic_options, NULL);
options = fill_table(data, options);
NMTST_EXPECT_NM_WARN("*invalid domain search*");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
g_test_assert_expected_messages();
- /* domain searches */
- g_assert_cmpint(nm_ip4_config_get_num_searches(ip4_config), ==, 0);
-
- g_hash_table_destroy(options);
+ strarr = nm_l3_config_data_get_searches(l3cd, AF_INET, &u);
+ g_assert_cmpint(u, ==, 0);
+ g_assert(!strarr);
}
static void
test_ip4_missing_prefix(const char *ip, guint32 expected_prefix)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const NMPlatformIP4Address * address;
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const NMPlatformIP4Address * address;
options = fill_table(generic_options, NULL);
g_hash_table_insert(options, "ip_address", (gpointer) ip);
g_hash_table_remove(options, "subnet_mask");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
- g_assert_cmpint(nm_ip4_config_get_num_addresses(ip4_config), ==, 1);
- address = _nmtst_ip4_config_get_address(ip4_config, 0);
+ g_assert_cmpint(nm_l3_config_data_get_num_addresses(l3cd, AF_INET), ==, 1);
+ address = nmtst_l3_config_data_get_address_at_4(l3cd, 0);
g_assert(address);
g_assert_cmpint(address->plen, ==, expected_prefix);
-
- g_hash_table_destroy(options);
}
static void
@@ -682,9 +649,9 @@ test_ip4_missing_prefix_8(void)
static void
test_ip4_prefix_classless(void)
{
- GHashTable * options;
- gs_unref_object NMIP4Config *ip4_config = NULL;
- const NMPlatformIP4Address * address;
+ gs_unref_hashtable GHashTable *options = NULL;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ const NMPlatformIP4Address * address;
/* Ensure that the missing-subnet-mask handler doesn't mangle classless
* subnet masks at all. The handler should trigger only if the server
@@ -695,14 +662,12 @@ test_ip4_prefix_classless(void)
g_hash_table_insert(options, "ip_address", "172.16.54.22");
g_hash_table_insert(options, "subnet_mask", "255.255.252.0");
- ip4_config = _ip4_config_from_options(1, "eth0", options, 0);
+ l3cd = _ip4_config_from_options(1, "eth0", options);
- g_assert_cmpint(nm_ip4_config_get_num_addresses(ip4_config), ==, 1);
- address = _nmtst_ip4_config_get_address(ip4_config, 0);
+ g_assert_cmpint(nm_l3_config_data_get_num_addresses(l3cd, AF_INET), ==, 1);
+ address = nmtst_l3_config_data_get_address_at_4(l3cd, 0);
g_assert(address);
g_assert_cmpint(address->plen, ==, 22);
-
- g_hash_table_destroy(options);
}
#define COMPARE_ID(src, is_str, expected, expected_len) \
diff --git a/src/core/dns/nm-dns-dnsmasq.c b/src/core/dns/nm-dns-dnsmasq.c
index 126e0a217a..b40521a32b 100644
--- a/src/core/dns/nm-dns-dnsmasq.c
+++ b/src/core/dns/nm-dns-dnsmasq.c
@@ -19,10 +19,9 @@
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-platform/nm-platform.h"
#include "nm-utils.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
#include "nm-dbus-manager.h"
#include "NetworkManagerUtils.h"
+#include "nm-l3-config-data.h"
#define PIDFILE NMRUNDIR "/dnsmasq.pid"
#define CONFDIR NMCONFDIR "/dnsmasq.d"
@@ -806,20 +805,22 @@ add_global_config(NMDnsDnsmasq * self,
static void
add_ip_config(NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsConfigIPData *ip_data)
{
- NMIPConfig * ip_config = ip_data->ip_config;
- gconstpointer addr;
- const char * iface, *domain;
+ const char * iface;
+ const char * domain;
char ip_addr_to_string_buf[IP_ADDR_TO_STRING_BUFLEN];
- int addr_family;
- guint i, j, num;
+ gconstpointer nameservers;
+ guint num;
+ guint i;
+ guint j;
- iface = nm_platform_link_get_name(NM_PLATFORM_GET, ip_data->data->ifindex);
- addr_family = nm_ip_config_get_addr_family(ip_config);
+ iface = nm_platform_link_get_name(NM_PLATFORM_GET, ip_data->data->ifindex);
- num = nm_ip_config_get_num_nameservers(ip_config);
+ nameservers = nm_l3_config_data_get_nameservers(ip_data->l3cd, ip_data->addr_family, &num);
for (i = 0; i < num; i++) {
- addr = nm_ip_config_get_nameserver(ip_config, i);
- ip_addr_to_string(addr_family, addr, iface, ip_addr_to_string_buf);
+ gconstpointer addr;
+
+ addr = nm_ip_addr_from_packed_array(ip_data->addr_family, nameservers, i);
+ ip_addr_to_string(ip_data->addr_family, addr, iface, ip_addr_to_string_buf);
if (!ip_data->domains.has_default_route_explicit && ip_data->domains.has_default_route)
add_dnsmasq_nameserver(self, servers, ip_addr_to_string_buf, NULL);
@@ -846,7 +847,7 @@ add_ip_config(NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsConfigIPD
static GVariant *
create_update_args(NMDnsDnsmasq * self,
const NMGlobalDnsConfig *global_config,
- const CList * ip_config_lst_head,
+ const CList * ip_data_lst_head,
const char * hostname)
{
GVariantBuilder servers;
@@ -857,7 +858,7 @@ create_update_args(NMDnsDnsmasq * self,
if (global_config)
add_global_config(self, &servers, global_config);
else {
- c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst)
+ c_list_for_each_entry (ip_data, ip_data_lst_head, ip_data_lst)
add_ip_config(self, &servers, ip_data);
}
@@ -1122,7 +1123,7 @@ start_dnsmasq(NMDnsDnsmasq *self, gboolean force_start, GError **error)
static gboolean
update(NMDnsPlugin * plugin,
const NMGlobalDnsConfig *global_config,
- const CList * ip_config_lst_head,
+ const CList * ip_data_lst_head,
const char * hostname,
GError ** error)
{
@@ -1134,7 +1135,7 @@ update(NMDnsPlugin * plugin,
nm_clear_pointer(&priv->set_server_ex_args, g_variant_unref);
priv->set_server_ex_args =
- g_variant_ref_sink(create_update_args(self, global_config, ip_config_lst_head, hostname));
+ g_variant_ref_sink(create_update_args(self, global_config, ip_data_lst_head, hostname));
send_dnsmasq_update(self);
return TRUE;
diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c
index f161b14c0d..e2d8e77f2e 100644
--- a/src/core/dns/nm-dns-manager.c
+++ b/src/core/dns/nm-dns-manager.c
@@ -7,6 +7,8 @@
#include "src/core/nm-default-daemon.h"
+#include "nm-dns-manager.h"
+
#include <fcntl.h>
#include <resolv.h>
#include <stdlib.h>
@@ -22,22 +24,20 @@
#include <libpsl.h>
#endif
-#include "libnm-glib-aux/nm-str-buf.h"
-#include "nm-utils.h"
#include "libnm-core-intern/nm-core-internal.h"
-#include "nm-dns-manager.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
+#include "libnm-glib-aux/nm-str-buf.h"
+
#include "NetworkManagerUtils.h"
+#include "devices/nm-device.h"
#include "nm-config.h"
#include "nm-dbus-object.h"
-#include "devices/nm-device.h"
-#include "nm-manager.h"
-
-#include "nm-dns-plugin.h"
#include "nm-dns-dnsmasq.h"
+#include "nm-dns-plugin.h"
#include "nm-dns-systemd-resolved.h"
#include "nm-dns-unbound.h"
+#include "nm-l3-config-data.h"
+#include "nm-manager.h"
+#include "nm-utils.h"
#define HASH_LEN NM_UTILS_CHECKSUM_LENGTH_SHA1
@@ -84,10 +84,10 @@ typedef struct {
GHashTable *configs_dict;
CList configs_lst_head;
- CList ip_config_lst_head;
+ CList ip_data_lst_head;
GVariant *config_variant;
- bool ip_config_lst_need_sort : 1;
+ bool ip_data_lst_need_sort : 1;
bool configs_lst_need_sort : 1;
@@ -159,11 +159,6 @@ NM_DEFINE_SINGLETON_GETTER(NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER
/*****************************************************************************/
-static void
-_ip_config_dns_priority_changed(gpointer config, GParamSpec *pspec, NMDnsConfigIPData *ip_data);
-
-/*****************************************************************************/
-
static gboolean
domain_is_valid(const char *domain, gboolean check_public_suffix)
{
@@ -208,6 +203,24 @@ static NM_UTILS_LOOKUP_STR_DEFINE(
/*****************************************************************************/
+static int
+_dns_config_ip_data_get_dns_priority1(const NML3ConfigData *l3cd, int addr_family)
+{
+ int prio;
+
+ if (!nm_l3_config_data_get_dns_priority(l3cd, addr_family, &prio))
+ return 0;
+
+ nm_assert(prio != 0);
+ return prio;
+}
+
+static int
+_dns_config_ip_data_get_dns_priority(const NMDnsConfigIPData *ip_data)
+{
+ return _dns_config_ip_data_get_dns_priority1(ip_data->l3cd, ip_data->addr_family);
+}
+
static void
_ASSERT_dns_config_data(const NMDnsConfigData *data)
{
@@ -221,9 +234,9 @@ _ASSERT_dns_config_ip_data(const NMDnsConfigIPData *ip_data)
{
nm_assert(ip_data);
_ASSERT_dns_config_data(ip_data->data);
- nm_assert(NM_IS_IP_CONFIG(ip_data->ip_config));
+ nm_assert(NM_IS_L3_CONFIG_DATA(ip_data->l3cd));
nm_assert(c_list_contains(&ip_data->data->data_lst_head, &ip_data->data_lst));
- nm_assert(ip_data->data->ifindex == nm_ip_config_get_ifindex(ip_data->ip_config));
+ nm_assert(ip_data->data->ifindex == nm_l3_config_data_get_ifindex(ip_data->l3cd));
#if NM_MORE_ASSERTS > 5
{
gboolean has_default = FALSE;
@@ -243,37 +256,36 @@ _ASSERT_dns_config_ip_data(const NMDnsConfigIPData *ip_data)
if (ip_data->domains.has_default_route_exclusive)
nm_assert(ip_data->domains.has_default_route);
}
+ nm_assert(_dns_config_ip_data_get_dns_priority(ip_data) != 0);
#endif
}
static NMDnsConfigIPData *
-_dns_config_ip_data_new(NMDnsConfigData * data,
- NMIPConfig * ip_config,
- NMDnsIPConfigType ip_config_type)
+_dns_config_ip_data_new(NMDnsConfigData * data,
+ int addr_family,
+ gconstpointer source_tag,
+ const NML3ConfigData *l3cd,
+ NMDnsIPConfigType ip_config_type)
{
NMDnsConfigIPData *ip_data;
_ASSERT_dns_config_data(data);
- nm_assert(NM_IS_IP_CONFIG(ip_config));
+ nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
nm_assert(ip_config_type != NM_DNS_IP_CONFIG_TYPE_REMOVED);
ip_data = g_slice_new(NMDnsConfigIPData);
*ip_data = (NMDnsConfigIPData){
.data = data,
- .ip_config = g_object_ref(ip_config),
+ .source_tag = source_tag,
+ .l3cd = nm_l3_config_data_ref_and_seal(l3cd),
.ip_config_type = ip_config_type,
+ .addr_family = addr_family,
};
c_list_link_tail(&data->data_lst_head, &ip_data->data_lst);
- c_list_link_tail(&NM_DNS_MANAGER_GET_PRIVATE(data->self)->ip_config_lst_head,
- &ip_data->ip_config_lst);
-
- /* We also need to set priv->ip_config_lst_need_sort, but the caller will do that! */
+ c_list_link_tail(&NM_DNS_MANAGER_GET_PRIVATE(data->self)->ip_data_lst_head,
+ &ip_data->ip_data_lst);
- g_signal_connect(ip_config,
- NM_IS_IP4_CONFIG(ip_config) ? "notify::" NM_IP4_CONFIG_DNS_PRIORITY
- : "notify::" NM_IP6_CONFIG_DNS_PRIORITY,
- (GCallback) _ip_config_dns_priority_changed,
- ip_data);
+ /* We also need to set priv->ip_data_lst_need_sort, but the caller will do that! */
_ASSERT_dns_config_ip_data(ip_data);
return ip_data;
@@ -285,35 +297,15 @@ _dns_config_ip_data_free(NMDnsConfigIPData *ip_data)
_ASSERT_dns_config_ip_data(ip_data);
c_list_unlink_stale(&ip_data->data_lst);
- c_list_unlink_stale(&ip_data->ip_config_lst);
+ c_list_unlink_stale(&ip_data->ip_data_lst);
g_free(ip_data->domains.search);
g_strfreev(ip_data->domains.reverse);
- g_signal_handlers_disconnect_by_func(ip_data->ip_config,
- _ip_config_dns_priority_changed,
- ip_data);
-
- g_object_unref(ip_data->ip_config);
+ nm_l3_config_data_unref(ip_data->l3cd);
nm_g_slice_free(ip_data);
}
-static NMDnsConfigIPData *
-_dns_config_data_find_ip_config(NMDnsConfigData *data, NMIPConfig *ip_config)
-{
- NMDnsConfigIPData *ip_data;
-
- _ASSERT_dns_config_data(data);
-
- c_list_for_each_entry (ip_data, &data->data_lst_head, data_lst) {
- _ASSERT_dns_config_ip_data(ip_data);
-
- if (ip_data->ip_config == ip_config)
- return ip_data;
- }
- return NULL;
-}
-
static void
_dns_config_data_free(NMDnsConfigData *data)
{
@@ -325,14 +317,13 @@ _dns_config_data_free(NMDnsConfigData *data)
}
static int
-_mgr_get_ip_config_lst_cmp(const CList *a_lst, const CList *b_lst, const void *user_data)
+_mgr_get_ip_data_lst_cmp(const CList *a_lst, const CList *b_lst, const void *user_data)
{
- const NMDnsConfigIPData *a = c_list_entry(a_lst, NMDnsConfigIPData, ip_config_lst);
- const NMDnsConfigIPData *b = c_list_entry(b_lst, NMDnsConfigIPData, ip_config_lst);
+ const NMDnsConfigIPData *a = c_list_entry(a_lst, NMDnsConfigIPData, ip_data_lst);
+ const NMDnsConfigIPData *b = c_list_entry(b_lst, NMDnsConfigIPData, ip_data_lst);
/* Configurations with lower priority value first */
- NM_CMP_DIRECT(nm_ip_config_get_dns_priority(a->ip_config),
- nm_ip_config_get_dns_priority(b->ip_config));
+ NM_CMP_DIRECT(_dns_config_ip_data_get_dns_priority(a), _dns_config_ip_data_get_dns_priority(b));
/* Sort according to type (descendingly) */
NM_CMP_FIELD(b, a, ip_config_type);
@@ -341,16 +332,16 @@ _mgr_get_ip_config_lst_cmp(const CList *a_lst, const CList *b_lst, const void *u
}
static CList *
-_mgr_get_ip_config_lst_head(NMDnsManager *self)
+_mgr_get_ip_data_lst_head(NMDnsManager *self)
{
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self);
- if (G_UNLIKELY(priv->ip_config_lst_need_sort)) {
- priv->ip_config_lst_need_sort = FALSE;
- c_list_sort(&priv->ip_config_lst_head, _mgr_get_ip_config_lst_cmp, NULL);
+ if (G_UNLIKELY(priv->ip_data_lst_need_sort)) {
+ priv->ip_data_lst_need_sort = FALSE;
+ c_list_sort(&priv->ip_data_lst_head, _mgr_get_ip_data_lst_cmp, NULL);
}
- return &priv->ip_config_lst_head;
+ return &priv->ip_data_lst_head;
}
static int
@@ -427,28 +418,33 @@ add_dns_option_item(GPtrArray *array, const char *str)
}
static void
-add_dns_domains(GPtrArray * array,
- const NMIPConfig *ip_config,
- gboolean include_routing,
- gboolean dup)
+add_dns_domains(GPtrArray * array,
+ int addr_family,
+ const NML3ConfigData *l3cd,
+ gboolean include_routing,
+ gboolean dup)
{
- guint num_domains, num_searches, i;
- const char *str;
+ const char *const *domains;
+ const char *const *searches;
+ guint num_domains;
+ guint num_searches;
+ guint i;
+ const char * str;
- num_domains = nm_ip_config_get_num_domains(ip_config);
- num_searches = nm_ip_config_get_num_searches(ip_config);
+ domains = nm_l3_config_data_get_domains(l3cd, addr_family, &num_domains);
+ searches = nm_l3_config_data_get_searches(l3cd, addr_family, &num_searches);
for (i = 0; i < num_searches; i++) {
- str = nm_ip_config_get_search(ip_config, i);
+ str = searches[i];
if (!include_routing && domain_is_routing(str))
continue;
if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE))
continue;
add_string_item(array, str, dup);
}
- if (num_domains > 1 || !num_searches) {
+ if (num_domains > 1 || num_searches == 0) {
for (i = 0; i < num_domains; i++) {
- str = nm_ip_config_get_domain(ip_config, i);
+ str = domains[i];
if (!include_routing && domain_is_routing(str))
continue;
if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE))
@@ -459,26 +455,24 @@ add_dns_domains(GPtrArray * array,
}
static void
-merge_one_ip_config(NMResolvConfData *rc, int ifindex, const NMIPConfig *ip_config)
+merge_one_l3cd(NMResolvConfData *rc, int addr_family, int ifindex, const NML3ConfigData *l3cd)
{
- int addr_family;
- char buf[NM_UTILS_INET_ADDRSTRLEN + 50];
- gboolean has_trust_ad;
- guint num_nameservers;
- guint num;
- guint i;
-
- addr_family = nm_ip_config_get_addr_family(ip_config);
+ char buf[NM_UTILS_INET_ADDRSTRLEN + 50];
+ gboolean has_trust_ad;
+ guint num_nameservers;
+ guint num;
+ guint i;
+ gconstpointer nameservers;
+ const char *const *strv;
- nm_assert_addr_family(addr_family);
- nm_assert(ifindex > 0);
- nm_assert(ifindex == nm_ip_config_get_ifindex(ip_config));
+ nm_assert(ifindex == nm_l3_config_data_get_ifindex(l3cd));
- num_nameservers = nm_ip_config_get_num_nameservers(ip_config);
+ nameservers = nm_l3_config_data_get_nameservers(l3cd, addr_family, &num_nameservers);
for (i = 0; i < num_nameservers; i++) {
const NMIPAddr *addr;
- addr = nm_ip_config_get_nameserver(ip_config, i);
+ addr = nm_ip_addr_from_packed_array(addr_family, nameservers, i);
+
if (addr_family == AF_INET)
nm_utils_inet_ntop(addr_family, addr, buf);
else if (IN6_IS_ADDR_V4MAPPED(addr))
@@ -499,22 +493,23 @@ merge_one_ip_config(NMResolvConfData *rc, int ifindex, const NMIPConfig *ip_conf
add_string_item(rc->nameservers, buf, TRUE);
}
- add_dns_domains(rc->searches, ip_config, FALSE, TRUE);
+ add_dns_domains(rc->searches, addr_family, l3cd, FALSE, TRUE);
has_trust_ad = FALSE;
- num = nm_ip_config_get_num_dns_options(ip_config);
+ strv = nm_l3_config_data_get_dns_options(l3cd, addr_family, &num);
for (i = 0; i < num; i++) {
- const char *option = nm_ip_config_get_dns_option(ip_config, i);
+ const char *option = strv[i];
if (nm_streq(option, NM_SETTING_DNS_OPTION_TRUST_AD)) {
has_trust_ad = TRUE;
continue;
}
- add_dns_option_item(rc->options, nm_ip_config_get_dns_option(ip_config, i));
+ add_dns_option_item(rc->options, option);
}
+
if (num_nameservers == 0) {
- /* If the @ip_config contributes no DNS servers, ignore whether trust-ad is set or unset
- * for this @ip_config. */
+ /* If the @l3cd contributes no DNS servers, ignore whether trust-ad is set or unset
+ * for this @l3cd. */
} else if (has_trust_ad) {
/* We only set has_trust_ad to TRUE, if all IP configs agree (or don't contribute).
* Once set to FALSE, it doesn't get reset. */
@@ -524,20 +519,17 @@ merge_one_ip_config(NMResolvConfData *rc, int ifindex, const NMIPConfig *ip_conf
rc->has_trust_ad = NM_TERNARY_FALSE;
if (addr_family == AF_INET) {
- const NMIP4Config *ip4_config = (const NMIP4Config *) ip_config;
+ const in_addr_t *nis_servers;
+ const char * nis_domain;
- /* NIS stuff */
- num = nm_ip4_config_get_num_nis_servers(ip4_config);
- for (i = 0; i < num; i++) {
- add_string_item(rc->nis_servers,
- _nm_utils_inet4_ntop(nm_ip4_config_get_nis_server(ip4_config, i), buf),
- TRUE);
- }
+ nis_servers = nm_l3_config_data_get_nis_servers(l3cd, &num);
+ for (i = 0; i < num; i++)
+ add_string_item(rc->nis_servers, _nm_utils_inet4_ntop(nis_servers[i], buf), TRUE);
- if (nm_ip4_config_get_nis_domain(ip4_config)) {
+ if ((nis_domain = nm_l3_config_data_get_nis_domain(l3cd))) {
/* FIXME: handle multiple domains */
if (!rc->nis_domain)
- rc->nis_domain = nm_ip4_config_get_nis_domain(ip4_config);
+ rc->nis_domain = nis_domain;
}
}
}
@@ -1119,9 +1111,9 @@ compute_hash(NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer[
/* FIXME(ip-config-checksum): this relies on the fact that an IP
* configuration without DNS parameters gives a zero checksum. */
- head = _mgr_get_ip_config_lst_head(self);
- c_list_for_each_entry (ip_data, head, ip_config_lst)
- nm_ip_config_hash(ip_data->ip_config, sum, TRUE);
+ head = _mgr_get_ip_data_lst_head(self);
+ c_list_for_each_entry (ip_data, head, ip_data_lst)
+ ; //XXX nm_ip_config_hash(ip_data->l3cd, sum, TRUE);
}
nm_utils_checksum_get_digest_len(sum, buffer, HASH_LEN);
@@ -1169,19 +1161,18 @@ merge_global_dns_config(NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
}
static const char *
-get_nameserver_list(const NMIPConfig *config, NMStrBuf *tmp_strbuf)
+get_nameserver_list(int addr_family, const NML3ConfigData *l3cd, NMStrBuf *tmp_strbuf)
{
- char buf[NM_UTILS_INET_ADDRSTRLEN];
- int addr_family;
- guint num;
- guint i;
+ char buf[NM_UTILS_INET_ADDRSTRLEN];
+ const char *const *strv;
+ guint num;
+ guint i;
nm_str_buf_reset(tmp_strbuf);
- addr_family = nm_ip_config_get_addr_family(config);
- num = nm_ip_config_get_num_nameservers(config);
+ strv = nm_l3_config_data_get_nameservers(l3cd, addr_family, &num);
for (i = 0; i < num; i++) {
- nm_utils_inet_ntop(addr_family, nm_ip_config_get_nameserver(config, i), buf);
+ nm_utils_inet_ntop(addr_family, strv[i], buf);
if (i > 0)
nm_str_buf_append_c(tmp_strbuf, ' ');
nm_str_buf_append(tmp_strbuf, buf);
@@ -1224,36 +1215,39 @@ _collect_resolv_conf_data(NMDnsManager * self,
merge_global_dns_config(&rc, global_config);
else {
nm_auto_str_buf NMStrBuf tmp_strbuf = NM_STR_BUF_INIT(0, FALSE);
- int prio;
int first_prio = 0;
const NMDnsConfigIPData *ip_data;
const CList * head;
gboolean is_first = TRUE;
- head = _mgr_get_ip_config_lst_head(self);
- c_list_for_each_entry (ip_data, head, ip_config_lst) {
+ head = _mgr_get_ip_data_lst_head(self);
+ c_list_for_each_entry (ip_data, head, ip_data_lst) {
gboolean skip = FALSE;
+ int dns_priority;
_ASSERT_dns_config_ip_data(ip_data);
- prio = nm_ip_config_get_dns_priority(ip_data->ip_config);
+ if (!nm_l3_config_data_get_dns_priority(ip_data->l3cd,
+ ip_data->addr_family,
+ &dns_priority))
+ nm_assert_not_reached();
if (is_first) {
is_first = FALSE;
- first_prio = prio;
- } else if (first_prio < 0 && first_prio != prio)
+ first_prio = dns_priority;
+ } else if (first_prio < 0 && first_prio != dns_priority)
skip = TRUE;
_LOGT("config: %8d %-7s v%c %-5d %s: %s",
- prio,
+ dns_priority,
_config_type_to_string(ip_data->ip_config_type),
- nm_utils_addr_family_to_char(nm_ip_config_get_addr_family(ip_data->ip_config)),
+ nm_utils_addr_family_to_char(ip_data->addr_family),
ip_data->data->ifindex,
skip ? "<SKIP>" : "",
- get_nameserver_list(ip_data->ip_config, &tmp_strbuf));
+ get_nameserver_list(ip_data->addr_family, ip_data->l3cd, &tmp_strbuf));
if (!skip)
- merge_one_ip_config(&rc, ip_data->data->ifindex, ip_data->ip_config);
+ merge_one_l3cd(&rc, ip_data->addr_family, ip_data->data->ifindex, ip_data->l3cd);
}
}
@@ -1289,27 +1283,32 @@ _collect_resolv_conf_data(NMDnsManager * self,
/*****************************************************************************/
static char **
-get_ip_rdns_domains(NMIPConfig *ip_config)
+get_ip_rdns_domains(int addr_family, const NML3ConfigData *l3cd)
{
- int addr_family = nm_ip_config_get_addr_family(ip_config);
- char ** strv;
- GPtrArray * domains;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIPAddress *address;
- const NMPlatformIPRoute * route;
-
- nm_assert_addr_family(addr_family);
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+ char ** strv;
+ GPtrArray * domains;
+ NMDedupMultiIter ipconf_iter;
+ const NMPObject *obj;
domains = g_ptr_array_sized_new(5);
- nm_ip_config_iter_ip_address_for_each (&ipconf_iter, ip_config, &address) {
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ l3cd,
+ &obj,
+ NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)) {
nm_utils_get_reverse_dns_domains_ip(addr_family,
- address->address_ptr,
- address->plen,
+ NMP_OBJECT_CAST_IP_ADDRESS(obj)->address_ptr,
+ NMP_OBJECT_CAST_IP_ADDRESS(obj)->plen,
domains);
}
- nm_ip_config_iter_ip_route_for_each (&ipconf_iter, ip_config, &route) {
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ l3cd,
+ &obj,
+ NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) {
+ const NMPlatformIPRoute *route = NMP_OBJECT_CAST_IP_ROUTE(obj);
+
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)) {
nm_utils_get_reverse_dns_domains_ip(addr_family,
route->network_ptr,
@@ -1391,12 +1390,12 @@ _mgr_configs_data_construct(NMDnsManager *self)
CList * head;
int prev_priority = G_MININT;
- head = _mgr_get_ip_config_lst_head(self);
+ head = _mgr_get_ip_data_lst_head(self);
#if NM_MORE_ASSERTS
/* we call _mgr_configs_data_clear() at the end of update. We
* don't expect any domain settings here. */
- c_list_for_each_entry (ip_data, head, ip_config_lst) {
+ c_list_for_each_entry (ip_data, head, ip_data_lst) {
nm_assert(!ip_data->domains.search);
nm_assert(!ip_data->domains.reverse);
nm_assert(!ip_data->domains.has_default_route_explicit);
@@ -1405,26 +1404,28 @@ _mgr_configs_data_construct(NMDnsManager *self)
}
#endif
- c_list_for_each_entry (ip_data, head, ip_config_lst) {
- NMIPConfig *ip_config = ip_data->ip_config;
- gboolean add_wildcard = FALSE;
+ c_list_for_each_entry (ip_data, head, ip_data_lst) {
+ gboolean add_wildcard = FALSE;
+ guint num;
- if (!nm_ip_config_get_num_nameservers(ip_config))
+ nm_l3_config_data_get_nameservers(ip_data->l3cd, ip_data->addr_family, &num);
+ if (num == 0)
continue;
- if (nm_ip_config_best_default_route_get(ip_config))
+ if (nm_l3_config_data_get_best_default_route(ip_data->l3cd, ip_data->addr_family)) {
+ /* FIXME(l3cfg): the best-default route of a l3cd is not significant! */
add_wildcard = TRUE;
- else {
+ } else {
/* If a VPN has never-default=no but doesn't get a default
* route (this can happen for example when the server
* pushes routes with openconnect), and there are no
* search or routing domains, then the name servers pushed
* by the server would be unused. It is preferable in this
* case to use the VPN DNS server for all queries. */
- if (ip_data->ip_config_type == NM_DNS_IP_CONFIG_TYPE_VPN
- && !nm_ip_config_get_never_default(ip_data->ip_config)
- && nm_ip_config_get_num_searches(ip_data->ip_config) == 0
- && nm_ip_config_get_num_domains(ip_data->ip_config) == 0)
- add_wildcard = TRUE;
+ //XXX if (ip_data->ip_config_type == NM_DNS_IP_CONFIG_TYPE_VPN
+ //XXX && !nm_ip_config_get_never_default(ip_data->ip_data->l3cd)
+ //XXX && nm_ip_config_get_num_searches(ip_data->ip_data->l3cd) == 0
+ //XXX && nm_ip_config_get_num_domains(ip_data->ip_data->l3cd) == 0)
+ //XXX add_wildcard = TRUE;
}
if (add_wildcard) {
@@ -1434,29 +1435,33 @@ _mgr_configs_data_construct(NMDnsManager *self)
}
}
- c_list_for_each_entry (ip_data, head, ip_config_lst) {
- NMIPConfig * ip_config = ip_data->ip_config;
- int priority;
- const char **domains;
- guint n_searches;
- guint n_domains;
- guint num_dom1;
- guint num_dom2;
- guint n_domains_allocated;
- guint i;
- gboolean has_default_route_maybe = FALSE;
- gboolean has_default_route_explicit = FALSE;
- gboolean has_default_route_auto = FALSE;
-
- if (!nm_ip_config_get_num_nameservers(ip_config))
+ c_list_for_each_entry (ip_data, head, ip_data_lst) {
+ int priority;
+ const char ** domains;
+ const char *const *strv_searches;
+ const char *const *strv_domains;
+ guint n_searches;
+ guint n_domains;
+ guint num_dom1;
+ guint num_dom2;
+ guint n_domains_allocated;
+ guint i;
+ gboolean has_default_route_maybe = FALSE;
+ gboolean has_default_route_explicit = FALSE;
+ gboolean has_default_route_auto = FALSE;
+ guint num;
+
+ nm_l3_config_data_get_nameservers(ip_data->l3cd, ip_data->addr_family, &num);
+ if (num == 0)
continue;
- n_searches = nm_ip_config_get_num_searches(ip_config);
- n_domains = nm_ip_config_get_num_domains(ip_config);
+ strv_searches =
+ nm_l3_config_data_get_searches(ip_data->l3cd, ip_data->addr_family, &n_searches);
+ strv_domains =
+ nm_l3_config_data_get_domains(ip_data->l3cd, ip_data->addr_family, &n_domains);
- priority = nm_ip_config_get_dns_priority(ip_config);
+ priority = _dns_config_ip_data_get_dns_priority(ip_data);
- nm_assert(priority != 0);
nm_assert(prev_priority <= priority);
prev_priority = priority;
@@ -1484,10 +1489,10 @@ _mgr_configs_data_construct(NMDnsManager *self)
/* searches are preferred over domains */
if (n_searches > 0) {
for (i = 0; i < n_searches; i++)
- domains[num_dom1++] = nm_ip_config_get_search(ip_config, i);
+ domains[num_dom1++] = strv_searches[i];
} else {
for (i = 0; i < n_domains; i++)
- domains[num_dom1++] = nm_ip_config_get_domain(ip_config, i);
+ domains[num_dom1++] = strv_domains[i];
}
nm_assert(num_dom1 < n_domains_allocated);
@@ -1575,8 +1580,8 @@ _mgr_configs_data_construct(NMDnsManager *self)
nm_assert(!ip_data->domains.search);
nm_assert(!ip_data->domains.reverse);
- ip_data->domains.search = domains;
- ip_data->domains.reverse = get_ip_rdns_domains(ip_config);
+ ip_data->domains.search = domains;
+ ip_data->domains.reverse = get_ip_rdns_domains(ip_data->addr_family, ip_data->l3cd);
ip_data->domains.has_default_route_explicit = has_default_route_explicit;
ip_data->domains.has_default_route_exclusive =
has_default_route_explicit || (priority < 0 && has_default_route_auto);
@@ -1608,8 +1613,8 @@ _mgr_configs_data_clear(NMDnsManager *self)
NMDnsConfigIPData *ip_data;
CList * head;
- head = _mgr_get_ip_config_lst_head(self);
- c_list_for_each_entry (ip_data, head, ip_config_lst) {
+ head = _mgr_get_ip_data_lst_head(self);
+ c_list_for_each_entry (ip_data, head, ip_data_lst) {
nm_clear_g_free(&ip_data->domains.search);
nm_clear_pointer(&ip_data->domains.reverse, g_strfreev);
ip_data->domains.has_default_route_explicit = FALSE;
@@ -1677,7 +1682,7 @@ update_dns(NMDnsManager *self, gboolean no_caching, gboolean force_emit, GError
if (priv->sd_resolve_plugin) {
nm_dns_plugin_update(priv->sd_resolve_plugin,
global_config,
- _mgr_get_ip_config_lst_head(self),
+ _mgr_get_ip_data_lst_head(self),
priv->hostname,
NULL);
}
@@ -1699,7 +1704,7 @@ update_dns(NMDnsManager *self, gboolean no_caching, gboolean force_emit, GError
_LOGD("update-dns: updating plugin %s", plugin_name);
if (!nm_dns_plugin_update(plugin,
global_config,
- _mgr_get_ip_config_lst_head(self),
+ _mgr_get_ip_data_lst_head(self),
priv->hostname,
&plugin_error)) {
_LOGW("update-dns: plugin %s update failed: %s", plugin_name, plugin_error->message);
@@ -1831,53 +1836,99 @@ plugin_skip:;
/*****************************************************************************/
-static void
-_ip_config_dns_priority_changed(gpointer config, GParamSpec *pspec, NMDnsConfigIPData *ip_data)
-{
- _ASSERT_dns_config_ip_data(ip_data);
-
- NM_DNS_MANAGER_GET_PRIVATE(ip_data->data->self)->ip_config_lst_need_sort = TRUE;
-}
-
gboolean
-nm_dns_manager_set_ip_config(NMDnsManager * self,
- NMIPConfig * ip_config,
- NMDnsIPConfigType ip_config_type)
+nm_dns_manager_set_ip_config(NMDnsManager * self,
+ int addr_family,
+ gconstpointer source_tag,
+ const NML3ConfigData *l3cd,
+ NMDnsIPConfigType ip_config_type,
+ gboolean replace_all)
{
NMDnsManagerPrivate *priv;
- NMDnsConfigIPData * ip_data;
NMDnsConfigData * data;
int ifindex;
+ gboolean changed = FALSE;
+ NMDnsConfigIPData * ip_data = NULL;
+ int dns_priority;
g_return_val_if_fail(NM_IS_DNS_MANAGER(self), FALSE);
- g_return_val_if_fail(NM_IS_IP_CONFIG(ip_config), FALSE);
+ g_return_val_if_fail(NM_IS_L3_CONFIG_DATA(l3cd), FALSE);
+ g_return_val_if_fail(source_tag, FALSE);
+
+ ifindex = nm_l3_config_data_get_ifindex(l3cd);
+ nm_assert(ifindex > 0);
- ifindex = nm_ip_config_get_ifindex(ip_config);
- g_return_val_if_fail(ifindex > 0, FALSE);
+ if (addr_family == AF_UNSPEC) {
+ /* Setting AF_UNSPEC is a shortcut for calling this function twice for AF_INET and
+ * AF_INET6. */
+ if (nm_dns_manager_set_ip_config(self,
+ AF_INET,
+ source_tag,
+ l3cd,
+ ip_config_type,
+ replace_all))
+ changed = TRUE;
+ if (nm_dns_manager_set_ip_config(self,
+ AF_INET6,
+ source_tag,
+ l3cd,
+ ip_config_type,
+ replace_all))
+ changed = TRUE;
+ return changed;
+ }
+
+ nm_assert_addr_family(addr_family);
priv = NM_DNS_MANAGER_GET_PRIVATE(self);
data = g_hash_table_lookup(priv->configs_dict, &ifindex);
- if (!data)
- ip_data = NULL;
- else
- ip_data = _dns_config_data_find_ip_config(data, ip_config);
- if (ip_config_type == NM_DNS_IP_CONFIG_TYPE_REMOVED) {
- if (!ip_data)
- return FALSE;
- /* deleting a config doesn't invalidate the configs' sort order. */
- _dns_config_ip_data_free(ip_data);
- if (c_list_is_empty(&data->data_lst_head))
- g_hash_table_remove(priv->configs_dict, &ifindex);
- goto changed;
+ if (data) {
+ NMDnsConfigIPData *ip_data_iter;
+ NMDnsConfigIPData *ip_data_safe;
+
+ c_list_for_each_entry_safe (ip_data_iter, ip_data_safe, &data->data_lst_head, data_lst) {
+ _ASSERT_dns_config_ip_data(ip_data_iter);
+
+ if (ip_data_iter->source_tag != source_tag)
+ continue;
+ if (ip_data_iter->addr_family != addr_family)
+ continue;
+
+ if (ip_config_type != NM_DNS_IP_CONFIG_TYPE_REMOVED && ip_data_iter->l3cd == l3cd) {
+ nm_assert(!ip_data);
+ ip_data = ip_data_iter;
+ continue;
+ }
+
+ if (!replace_all && l3cd && ip_data_iter->l3cd != l3cd)
+ continue;
+
+ changed = TRUE;
+ _dns_config_ip_data_free(ip_data_iter);
+ }
}
+ if (ip_config_type == NM_DNS_IP_CONFIG_TYPE_REMOVED)
+ goto done;
+
+ if (!l3cd)
+ goto done;
+
if (ip_data && ip_data->ip_config_type == ip_config_type) {
/* nothing to do. */
- return FALSE;
+ goto done;
+ }
+
+ dns_priority = _dns_config_ip_data_get_dns_priority1(l3cd, addr_family);
+ if (dns_priority == 0) {
+ /* no DNS priority for this address family. Skip it! */
+ goto done;
}
+ changed = TRUE;
+
if (!data) {
data = g_slice_new(NMDnsConfigData);
*data = (NMDnsConfigData){
@@ -1892,13 +1943,26 @@ nm_dns_manager_set_ip_config(NMDnsManager * self,
}
if (!ip_data)
- ip_data = _dns_config_ip_data_new(data, ip_config, ip_config_type);
+ ip_data = _dns_config_ip_data_new(data, addr_family, source_tag, l3cd, ip_config_type);
else
ip_data->ip_config_type = ip_config_type;
- priv->ip_config_lst_need_sort = TRUE;
+ priv->ip_data_lst_need_sort = TRUE;
+
+ nm_assert(l3cd);
+ nm_assert(ip_config_type != NM_DNS_IP_CONFIG_TYPE_REMOVED);
+ nm_assert(ip_data->addr_family == addr_family);
+ nm_assert(ip_data->source_tag == source_tag);
+ nm_assert(ip_data->l3cd == l3cd);
+ nm_assert(ip_data->ip_config_type == ip_config_type);
+
+done:
+ if (!changed)
+ return FALSE;
+
+ if (data && c_list_is_empty(&data->data_lst_head))
+ g_hash_table_remove(priv->configs_dict, &ifindex);
-changed:
if (!priv->updates_queue) {
gs_free_error GError *error = NULL;
@@ -2418,51 +2482,54 @@ _get_config_variant(NMDnsManager *self)
g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
- head = _mgr_get_ip_config_lst_head(self);
- c_list_for_each_entry (ip_data, head, ip_config_lst) {
- const NMIPConfig *ip_config = ip_data->ip_config;
- GVariantBuilder entry_builder;
- GVariantBuilder strv_builder;
- guint i, num;
- const int addr_family = nm_ip_config_get_addr_family(ip_config);
- char buf[NM_UTILS_INET_ADDRSTRLEN];
- const NMIPAddr * addr;
- const char * ifname;
-
- num = nm_ip_config_get_num_nameservers(ip_config);
- if (!num)
+ head = _mgr_get_ip_data_lst_head(self);
+ c_list_for_each_entry (ip_data, head, ip_data_lst) {
+ GVariantBuilder entry_builder;
+ GVariantBuilder strv_builder;
+ guint num;
+ guint num_domains;
+ guint num_searches;
+ guint i;
+ char buf[NM_UTILS_INET_ADDRSTRLEN];
+ const char * ifname;
+ gconstpointer nameservers;
+
+ nameservers = nm_l3_config_data_get_nameservers(ip_data->l3cd, ip_data->addr_family, &num);
+ if (num == 0)
continue;
g_variant_builder_init(&entry_builder, G_VARIANT_TYPE("a{sv}"));
g_variant_builder_init(&strv_builder, G_VARIANT_TYPE("as"));
for (i = 0; i < num; i++) {
- addr = nm_ip_config_get_nameserver(ip_config, i);
- g_variant_builder_add(&strv_builder, "s", nm_utils_inet_ntop(addr_family, addr, buf));
+ const NMIPAddr *addr;
+
+ addr = nm_ip_addr_from_packed_array(ip_data->addr_family, nameservers, i);
+ g_variant_builder_add(&strv_builder,
+ "s",
+ nm_utils_inet_ntop(ip_data->addr_family, addr, buf));
}
g_variant_builder_add(&entry_builder,
"{sv}",
"nameservers",
g_variant_builder_end(&strv_builder));
- num = nm_ip_config_get_num_domains(ip_config);
- num += nm_ip_config_get_num_searches(ip_config);
+ nm_l3_config_data_get_domains(ip_data->l3cd, ip_data->addr_family, &num_domains);
+ nm_l3_config_data_get_searches(ip_data->l3cd, ip_data->addr_family, &num_searches);
+ num = num_domains + num_searches;
if (num > 0) {
if (!array_domains)
array_domains = g_ptr_array_sized_new(num);
else
g_ptr_array_set_size(array_domains, 0);
- add_dns_domains(array_domains, ip_config, TRUE, FALSE);
+ add_dns_domains(array_domains, ip_data->addr_family, ip_data->l3cd, TRUE, FALSE);
if (array_domains->len) {
- g_variant_builder_init(&strv_builder, G_VARIANT_TYPE("as"));
- for (i = 0; i < array_domains->len; i++) {
- g_variant_builder_add(&strv_builder, "s", array_domains->pdata[i]);
- }
g_variant_builder_add(&entry_builder,
"{sv}",
"domains",
- g_variant_builder_end(&strv_builder));
+ g_variant_new_strv((const char *const *) array_domains->pdata,
+ array_domains->len));
}
}
@@ -2477,7 +2544,7 @@ _get_config_variant(NMDnsManager *self)
g_variant_builder_add(&entry_builder,
"{sv}",
"priority",
- g_variant_new_int32(nm_ip_config_get_dns_priority(ip_config)));
+ g_variant_new_int32(_dns_config_ip_data_get_dns_priority(ip_data)));
g_variant_builder_add(
&entry_builder,
@@ -2524,7 +2591,7 @@ nm_dns_manager_init(NMDnsManager *self)
_LOGT("creating...");
c_list_init(&priv->configs_lst_head);
- c_list_init(&priv->ip_config_lst_head);
+ c_list_init(&priv->ip_data_lst_head);
priv->config = g_object_ref(nm_config_get());
@@ -2562,7 +2629,7 @@ dispose(GObject *object)
g_clear_object(&priv->sd_resolve_plugin);
_clear_plugin(self);
- c_list_for_each_entry_safe (ip_data, ip_data_safe, &priv->ip_config_lst_head, ip_config_lst)
+ c_list_for_each_entry_safe (ip_data, ip_data_safe, &priv->ip_data_lst_head, ip_data_lst)
_dns_config_ip_data_free(ip_data);
nm_clear_pointer(&priv->configs_dict, g_hash_table_destroy);
diff --git a/src/core/dns/nm-dns-manager.h b/src/core/dns/nm-dns-manager.h
index 937ba62a05..22f5963534 100644
--- a/src/core/dns/nm-dns-manager.h
+++ b/src/core/dns/nm-dns-manager.h
@@ -8,8 +8,7 @@
#ifndef __NETWORKMANAGER_DNS_MANAGER_H__
#define __NETWORKMANAGER_DNS_MANAGER_H__
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
+#include "c-list/src/c-list.h"
#include "nm-setting-connection.h"
typedef enum {
@@ -32,10 +31,12 @@ struct _NMDnsManager;
typedef struct {
struct _NMDnsConfigData *data;
- NMIPConfig * ip_config;
+ gconstpointer source_tag;
+ const NML3ConfigData * l3cd;
CList data_lst;
- CList ip_config_lst;
+ CList ip_data_lst;
NMDnsIPConfigType ip_config_type;
+ int addr_family;
struct {
const char **search;
char ** reverse;
@@ -101,9 +102,12 @@ NMDnsManager *nm_dns_manager_get(void);
void nm_dns_manager_begin_updates(NMDnsManager *self, const char *func);
void nm_dns_manager_end_updates(NMDnsManager *self, const char *func);
-gboolean nm_dns_manager_set_ip_config(NMDnsManager * self,
- NMIPConfig * ip_config,
- NMDnsIPConfigType ip_config_type);
+gboolean nm_dns_manager_set_ip_config(NMDnsManager * self,
+ int addr_family,
+ gconstpointer source_tag,
+ const NML3ConfigData *l3cd,
+ NMDnsIPConfigType ip_config_type,
+ gboolean replace_all);
void nm_dns_manager_set_initial_hostname(NMDnsManager *self, const char *hostname);
void nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean skip_update);
diff --git a/src/core/dns/nm-dns-systemd-resolved.c b/src/core/dns/nm-dns-systemd-resolved.c
index 972ef643a3..0207c984a1 100644
--- a/src/core/dns/nm-dns-systemd-resolved.c
+++ b/src/core/dns/nm-dns-systemd-resolved.c
@@ -21,10 +21,9 @@
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-platform/nm-platform.h"
#include "nm-utils.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
#include "nm-dbus-manager.h"
#include "nm-manager.h"
+#include "nm-l3-config-data.h"
#include "nm-setting-connection.h"
#include "devices/nm-device.h"
#include "NetworkManagerUtils.h"
@@ -230,40 +229,42 @@ static gboolean
update_add_ip_config(NMDnsSystemdResolved *self,
GVariantBuilder * dns,
GVariantBuilder * domains,
- NMDnsConfigIPData * data)
+ NMDnsConfigIPData * ip_data)
{
- int addr_family;
- gsize addr_size;
- guint i, n;
- gboolean is_routing;
- const char *domain;
- gboolean has_config = FALSE;
-
- addr_family = nm_ip_config_get_addr_family(data->ip_config);
- addr_size = nm_utils_addr_family_to_size(addr_family);
-
- if ((!data->domains.search || !data->domains.search[0])
- && !data->domains.has_default_route_exclusive && !data->domains.has_default_route)
+ gsize addr_size;
+ guint n;
+ guint i;
+ gboolean is_routing;
+ const char * domain;
+ gboolean has_config = FALSE;
+ gconstpointer nameservers;
+
+ addr_size = nm_utils_addr_family_to_size(ip_data->addr_family);
+
+ if ((!ip_data->domains.search || !ip_data->domains.search[0])
+ && !ip_data->domains.has_default_route_exclusive && !ip_data->domains.has_default_route)
return FALSE;
- n = nm_ip_config_get_num_nameservers(data->ip_config);
+ nameservers = nm_l3_config_data_get_nameservers(ip_data->l3cd, ip_data->addr_family, &n);
for (i = 0; i < n; i++) {
g_variant_builder_open(dns, G_VARIANT_TYPE("(iay)"));
- g_variant_builder_add(dns, "i", addr_family);
+ g_variant_builder_add(dns, "i", ip_data->addr_family);
g_variant_builder_add_value(
dns,
- nm_g_variant_new_ay(nm_ip_config_get_nameserver(data->ip_config, i), addr_size));
+ nm_g_variant_new_ay(nm_ip_addr_from_packed_array(ip_data->addr_family, nameservers, i),
+ addr_size));
g_variant_builder_close(dns);
has_config = TRUE;
}
- if (!data->domains.has_default_route_explicit && data->domains.has_default_route_exclusive) {
+ if (!ip_data->domains.has_default_route_explicit
+ && ip_data->domains.has_default_route_exclusive) {
g_variant_builder_add(domains, "(sb)", ".", TRUE);
has_config = TRUE;
}
- if (data->domains.search) {
- for (i = 0; data->domains.search[i]; i++) {
- domain = nm_utils_parse_dns_domain(data->domains.search[i], &is_routing);
+ if (ip_data->domains.search) {
+ for (i = 0; ip_data->domains.search[i]; i++) {
+ domain = nm_utils_parse_dns_domain(ip_data->domains.search[i], &is_routing);
g_variant_builder_add(domains, "(sb)", domain[0] ? domain : ".", is_routing);
has_config = TRUE;
}
@@ -304,17 +305,16 @@ prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
g_variant_builder_open(&domains, G_VARIANT_TYPE("a(sb)"));
c_list_for_each_entry (elem, &ic->configs_lst_head, lst) {
- NMDnsConfigIPData *data = elem->data;
- NMIPConfig * ip_config = data->ip_config;
+ NMDnsConfigIPData *ip_data = elem->data;
- has_config |= update_add_ip_config(self, &dns, &domains, data);
+ has_config |= update_add_ip_config(self, &dns, &domains, ip_data);
- if (data->domains.has_default_route)
+ if (ip_data->domains.has_default_route)
has_default_route = TRUE;
- if (NM_IS_IP4_CONFIG(ip_config)) {
- mdns = NM_MAX(mdns, nm_ip4_config_mdns_get(NM_IP4_CONFIG(ip_config)));
- llmnr = NM_MAX(llmnr, nm_ip4_config_llmnr_get(NM_IP4_CONFIG(ip_config)));
+ if (NM_IS_IPv4(ip_data->addr_family)) {
+ mdns = NM_MAX(mdns, nm_l3_config_data_get_mdns(ip_data->l3cd));
+ llmnr = NM_MAX(llmnr, nm_l3_config_data_get_llmnr(ip_data->l3cd));
}
}
@@ -513,7 +513,7 @@ start_resolve:
static gboolean
update(NMDnsPlugin * plugin,
const NMGlobalDnsConfig *global_config,
- const CList * ip_config_lst_head,
+ const CList * ip_data_lst_head,
const char * hostname,
GError ** error)
{
@@ -531,11 +531,11 @@ update(NMDnsPlugin * plugin,
interfaces =
g_hash_table_new_full(nm_direct_hash, NULL, NULL, (GDestroyNotify) _interface_config_free);
- c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst) {
+ c_list_for_each_entry (ip_data, ip_data_lst_head, ip_data_lst) {
InterfaceConfig *ic = NULL;
ifindex = ip_data->data->ifindex;
- nm_assert(ifindex == nm_ip_config_get_ifindex(ip_data->ip_config));
+ nm_assert(ifindex == nm_l3_config_data_get_ifindex(ip_data->l3cd));
ic = g_hash_table_lookup(interfaces, GINT_TO_POINTER(ifindex));
if (!ic) {
diff --git a/src/core/dnsmasq/nm-dnsmasq-manager.c b/src/core/dnsmasq/nm-dnsmasq-manager.c
index e8697e817e..f4eea33a13 100644
--- a/src/core/dnsmasq/nm-dnsmasq-manager.c
+++ b/src/core/dnsmasq/nm-dnsmasq-manager.c
@@ -17,6 +17,7 @@
#include "nm-dnsmasq-utils.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
+#include "nm-l3-config-data.h"
#include "libnm-core-intern/nm-core-internal.h"
#define CONFDIR NMCONFDIR "/dnsmasq-shared.d"
@@ -85,24 +86,28 @@ dm_watch_cb(GPid pid, int status, gpointer user_data)
}
static GPtrArray *
-create_dm_cmd_line(const char * iface,
- const NMIP4Config *ip4_config,
- const char * pidfile,
- gboolean announce_android_metered,
- GError ** error)
+create_dm_cmd_line(const char * iface,
+ const NML3ConfigData *l3cd,
+ const char * pidfile,
+ gboolean announce_android_metered,
+ GError ** error)
{
gs_unref_ptrarray GPtrArray *cmd = NULL;
nm_auto_free_gstring GString *s = NULL;
char first[INET_ADDRSTRLEN];
char last[INET_ADDRSTRLEN];
char listen_address_s[INET_ADDRSTRLEN];
- char tmpaddr[INET_ADDRSTRLEN];
+ char sbuf_addr[INET_ADDRSTRLEN];
gs_free char * error_desc = NULL;
const char * dm_binary;
const NMPlatformIP4Address * listen_address;
- guint i, n;
+ const in_addr_t * ipv4arr;
+ const char *const * strarr;
+ guint n;
+ guint i;
- listen_address = nm_ip4_config_get_first_address(ip4_config);
+ listen_address = NMP_OBJECT_CAST_IP4_ADDRESS(
+ nm_l3_config_data_get_first_obj(l3cd, NMP_OBJECT_TYPE_IP4_ADDRESS, NULL));
g_return_val_if_fail(listen_address, NULL);
@@ -151,28 +156,28 @@ create_dm_cmd_line(const char * iface,
nm_strv_ptrarray_add_string_printf(cmd, "--dhcp-range=%s,%s,60m", first, last);
- if (nm_ip4_config_best_default_route_get(ip4_config)) {
+ if (nm_l3_config_data_get_best_default_route(l3cd, AF_INET)) {
nm_strv_ptrarray_add_string_concat(cmd, "--dhcp-option=option:router,", listen_address_s);
}
- if ((n = nm_ip4_config_get_num_nameservers(ip4_config))) {
+ ipv4arr = nm_l3_config_data_get_nameservers(l3cd, AF_INET, &n);
+ if (n > 0) {
nm_gstring_prepare(&s);
g_string_append(s, "--dhcp-option=option:dns-server");
for (i = 0; i < n; i++) {
g_string_append_c(s, ',');
- g_string_append(
- s,
- _nm_utils_inet4_ntop(nm_ip4_config_get_nameserver(ip4_config, i), tmpaddr));
+ g_string_append(s, _nm_utils_inet4_ntop(ipv4arr[i], sbuf_addr));
}
nm_strv_ptrarray_take_gstring(cmd, &s);
}
- if ((n = nm_ip4_config_get_num_searches(ip4_config))) {
+ strarr = nm_l3_config_data_get_searches(l3cd, AF_INET, &n);
+ if (n > 0) {
nm_gstring_prepare(&s);
g_string_append(s, "--dhcp-option=option:domain-search");
for (i = 0; i < n; i++) {
g_string_append_c(s, ',');
- g_string_append(s, nm_ip4_config_get_search(ip4_config, i));
+ g_string_append(s, strarr[i]);
}
nm_strv_ptrarray_take_gstring(cmd, &s);
}
@@ -237,25 +242,25 @@ out:
}
gboolean
-nm_dnsmasq_manager_start(NMDnsMasqManager *manager,
- NMIP4Config * ip4_config,
- gboolean announce_android_metered,
- GError ** error)
+nm_dnsmasq_manager_start(NMDnsMasqManager * manager,
+ const NML3ConfigData *l3cd,
+ gboolean announce_android_metered,
+ GError ** error)
{
- NMDnsMasqManagerPrivate *priv;
gs_unref_ptrarray GPtrArray *dm_cmd = NULL;
gs_free char * cmd_str = NULL;
+ NMDnsMasqManagerPrivate * priv;
g_return_val_if_fail(NM_IS_DNSMASQ_MANAGER(manager), FALSE);
g_return_val_if_fail(!error || !*error, FALSE);
- g_return_val_if_fail(nm_ip4_config_get_num_addresses(ip4_config) > 0, FALSE);
+ g_return_val_if_fail(NM_IS_L3_CONFIG_DATA(l3cd), FALSE);
+ g_return_val_if_fail(nm_l3_config_data_get_num_addresses(l3cd, AF_INET) > 0, FALSE);
priv = NM_DNSMASQ_MANAGER_GET_PRIVATE(manager);
kill_existing_by_pidfile(priv->pidfile);
- dm_cmd =
- create_dm_cmd_line(priv->iface, ip4_config, priv->pidfile, announce_android_metered, error);
+ dm_cmd = create_dm_cmd_line(priv->iface, l3cd, priv->pidfile, announce_android_metered, error);
if (!dm_cmd)
return FALSE;
diff --git a/src/core/dnsmasq/nm-dnsmasq-manager.h b/src/core/dnsmasq/nm-dnsmasq-manager.h
index 272d1cead1..78ca37251e 100644
--- a/src/core/dnsmasq/nm-dnsmasq-manager.h
+++ b/src/core/dnsmasq/nm-dnsmasq-manager.h
@@ -6,8 +6,6 @@
#ifndef __NETWORKMANAGER_DNSMASQ_MANAGER_H__
#define __NETWORKMANAGER_DNSMASQ_MANAGER_H__
-#include "nm-ip4-config.h"
-
#define NM_TYPE_DNSMASQ_MANAGER (nm_dnsmasq_manager_get_type())
#define NM_DNSMASQ_MANAGER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DNSMASQ_MANAGER, NMDnsMasqManager))
@@ -35,10 +33,10 @@ GType nm_dnsmasq_manager_get_type(void);
NMDnsMasqManager *nm_dnsmasq_manager_new(const char *iface);
-gboolean nm_dnsmasq_manager_start(NMDnsMasqManager *manager,
- NMIP4Config * ip4_config,
- gboolean announce_android_metered,
- GError ** error);
+gboolean nm_dnsmasq_manager_start(NMDnsMasqManager * manager,
+ const NML3ConfigData *l3cd,
+ gboolean announce_android_metered,
+ GError ** error);
void nm_dnsmasq_manager_stop(NMDnsMasqManager *manager);
diff --git a/src/core/meson.build b/src/core/meson.build
index f4d7af6407..2ab8b664fd 100644
--- a/src/core/meson.build
+++ b/src/core/meson.build
@@ -53,8 +53,6 @@ libNetworkManagerBase = static_library(
'nm-l3-ipv4ll.c',
'nm-l3cfg.c',
'nm-ip-config.c',
- 'nm-ip4-config.c',
- 'nm-ip6-config.c',
),
dependencies: [
core_default_dep,
@@ -92,7 +90,6 @@ endif
libNetworkManager = static_library(
'NetworkManager',
sources: files(
- 'devices/nm-acd-manager.c',
'devices/nm-device-6lowpan.c',
'devices/nm-device-bond.c',
'devices/nm-device-bridge.c',
@@ -168,7 +165,6 @@ libNetworkManager = static_library(
'nm-manager.c',
'nm-pacrunner-manager.c',
'nm-policy.c',
- 'nm-proxy-config.c',
'nm-rfkill-manager.c',
'nm-session-monitor.c',
'nm-sleep-monitor.c',
diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c
index cf1b58ecf4..2dce07871e 100644
--- a/src/core/ndisc/nm-ndisc.c
+++ b/src/core/ndisc/nm-ndisc.c
@@ -16,6 +16,7 @@
#include "nm-utils.h"
#include "libnm-platform/nm-platform.h"
#include "libnm-platform/nmp-netns.h"
+#include "libnm-platform/nm-platform-utils.h"
#include "nm-l3-config-data.h"
#define _NMLOG_PREFIX_NAME "ndisc"
@@ -101,8 +102,6 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex * multi_idx,
int ifindex,
const NMNDiscData * rdata,
NMSettingIP6ConfigPrivacy ip6_privacy,
- guint32 route_table,
- guint32 route_metric,
gboolean kernel_support_rta_pref,
gboolean kernel_support_extended_ifa_flags)
{
@@ -166,8 +165,10 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex * multi_idx,
.plen = ndisc_route->plen,
.gateway = ndisc_route->gateway,
.rt_source = NM_IP_CONFIG_SOURCE_NDISC,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
.rt_pref = ndisc_route->preference,
};
nm_assert((NMIcmpv6RouterPref) r.rt_pref == ndisc_route->preference);
@@ -180,8 +181,10 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex * multi_idx,
NMPlatformIP6Route r = {
.rt_source = NM_IP_CONFIG_SOURCE_NDISC,
.ifindex = ifindex,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
for (i = 0; i < rdata->gateways_n; i++) {
@@ -983,30 +986,85 @@ announce_router_solicited(NMNDisc *ndisc)
/*****************************************************************************/
void
-nm_ndisc_set_config(NMNDisc * ndisc,
- const GArray *addresses,
- const GArray *dns_servers,
- const GArray *dns_domains)
+nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd)
{
- gboolean changed = FALSE;
- guint i;
+ gboolean changed = FALSE;
+ const struct in6_addr *in6arr;
+ const char *const * strvarr;
+ NMDedupMultiIter iter;
+ const NMPObject * obj;
+ gint64 now_msec;
+ guint len;
+ guint i;
+
+ nm_assert(NM_IS_NDISC(ndisc));
+ nm_assert(nm_ndisc_get_node_type(ndisc) == NM_NDISC_NODE_TYPE_ROUTER);
- for (i = 0; i < addresses->len; i++) {
- if (nm_ndisc_add_address(ndisc, &g_array_index(addresses, NMNDiscAddress, i), 0, FALSE))
+ now_msec = nm_utils_get_monotonic_timestamp_msec();
+
+ nm_l3_config_data_iter_obj_for_each (&iter, l3cd, &obj, NMP_OBJECT_TYPE_IP6_ADDRESS) {
+ const NMPlatformIP6Address *addr = NMP_OBJECT_CAST_IP6_ADDRESS(obj);
+ guint32 preferred;
+ guint32 lifetime;
+ NMNDiscAddress a;
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&addr->address) || IN6_IS_ADDR_LINKLOCAL(&addr->address))
+ continue;
+
+ if (addr->n_ifa_flags & IFA_F_TENTATIVE || addr->n_ifa_flags & IFA_F_DADFAILED)
+ continue;
+
+ if (addr->plen != 64)
+ continue;
+
+ lifetime = nmp_utils_lifetime_get(addr->timestamp,
+ addr->lifetime,
+ addr->preferred,
+ NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000,
+ &preferred);
+ if (!lifetime)
+ continue;
+
+ a = (NMNDiscAddress){
+ .address = addr->address,
+ .expiry_msec = _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, lifetime),
+ .expiry_preferred_msec =
+ _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, preferred),
+ };
+
+ if (nm_ndisc_add_address(ndisc, &a, now_msec, FALSE))
changed = TRUE;
}
- for (i = 0; i < dns_servers->len; i++) {
- if (nm_ndisc_add_dns_server(ndisc,
- &g_array_index(dns_servers, NMNDiscDNSServer, i),
- G_MININT64))
+ in6arr = NULL;
+ len = 0;
+ if (l3cd)
+ in6arr = nm_l3_config_data_get_nameservers(l3cd, AF_INET6, &len);
+ for (i = 0; i < len; i++) {
+ NMNDiscDNSServer n;
+
+ n = (NMNDiscDNSServer){
+ .address = in6arr[i],
+ .expiry_msec = _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP,
+ NM_NDISC_ROUTER_LIFETIME),
+ };
+ if (nm_ndisc_add_dns_server(ndisc, &n, G_MININT64))
changed = TRUE;
}
- for (i = 0; i < dns_domains->len; i++) {
- if (nm_ndisc_add_dns_domain(ndisc,
- &g_array_index(dns_domains, NMNDiscDNSDomain, i),
- G_MININT64))
+ strvarr = NULL;
+ len = 0;
+ if (l3cd)
+ strvarr = nm_l3_config_data_get_searches(l3cd, AF_INET6, &len);
+ for (i = 0; i < len; i++) {
+ NMNDiscDNSDomain n;
+
+ n = (NMNDiscDNSDomain){
+ .domain = (char *) strvarr[i],
+ .expiry_msec = _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP,
+ NM_NDISC_ROUTER_LIFETIME),
+ };
+ if (nm_ndisc_add_dns_domain(ndisc, &n, G_MININT64))
changed = TRUE;
}
diff --git a/src/core/ndisc/nm-ndisc.h b/src/core/ndisc/nm-ndisc.h
index 15f95d206d..bbcfad311c 100644
--- a/src/core/ndisc/nm-ndisc.h
+++ b/src/core/ndisc/nm-ndisc.h
@@ -226,10 +226,7 @@ void nm_ndisc_start(NMNDisc *ndisc);
void nm_ndisc_stop(NMNDisc *ndisc);
NMNDiscConfigMap
nm_ndisc_dad_failed(NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal);
-void nm_ndisc_set_config(NMNDisc * ndisc,
- const GArray *addresses,
- const GArray *dns_servers,
- const GArray *dns_domains);
+void nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd);
NMPlatform *nm_ndisc_get_platform(NMNDisc *self);
NMPNetns * nm_ndisc_netns_get(NMNDisc *self);
@@ -270,8 +267,6 @@ struct _NML3ConfigData *nm_ndisc_data_to_l3cd(NMDedupMultiIndex * multi_id
int ifindex,
const NMNDiscData * rdata,
NMSettingIP6ConfigPrivacy ip6_privacy,
- guint32 route_table,
- guint32 route_metric,
gboolean kernel_support_rta_pref,
gboolean kernel_support_extended_ifa_flags);
diff --git a/src/core/nm-act-request.c b/src/core/nm-act-request.c
index d0a2e0c783..58dd4a87f8 100644
--- a/src/core/nm-act-request.c
+++ b/src/core/nm-act-request.c
@@ -24,8 +24,7 @@
#include "settings/nm-settings-connection.h"
typedef struct {
- CList call_ids_lst_head;
- NMFirewallConfig *firewall_config;
+ CList call_ids_lst_head;
} NMActRequestPrivate;
struct _NMActRequest {
@@ -250,36 +249,6 @@ nm_act_request_clear_secrets(NMActRequest *self)
/*****************************************************************************/
-NMFirewallConfig *
-nm_act_request_get_shared(NMActRequest *req)
-{
- g_return_val_if_fail(NM_IS_ACT_REQUEST(req), FALSE);
-
- return NM_ACT_REQUEST_GET_PRIVATE(req)->firewall_config;
-}
-
-void
-nm_act_request_set_shared(NMActRequest *req, NMFirewallConfig *rules)
-{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE(req);
-
- g_return_if_fail(NM_IS_ACT_REQUEST(req));
-
- if (priv->firewall_config == rules)
- return;
-
- if (priv->firewall_config) {
- nm_firewall_config_apply(priv->firewall_config, FALSE);
- priv->firewall_config = NULL;
- }
- if (rules) {
- priv->firewall_config = rules;
- nm_firewall_config_apply(priv->firewall_config, TRUE);
- }
-}
-
-/*****************************************************************************/
-
static void
device_notify(GObject *object, GParamSpec *pspec, gpointer self)
{
@@ -508,11 +477,6 @@ dispose(GObject *object)
c_list_for_each_entry_safe (call_id, call_id_safe, &priv->call_ids_lst_head, call_ids_lst)
_do_cancel_secrets(self, call_id, TRUE);
- if (priv->firewall_config) {
- nm_firewall_config_apply(priv->firewall_config, FALSE);
- nm_clear_pointer(&priv->firewall_config, nm_firewall_config_free);
- }
-
G_OBJECT_CLASS(nm_act_request_parent_class)->dispose(object);
}
diff --git a/src/core/nm-act-request.h b/src/core/nm-act-request.h
index 9c702d31eb..698a9985a4 100644
--- a/src/core/nm-act-request.h
+++ b/src/core/nm-act-request.h
@@ -38,14 +38,6 @@ NMConnection *nm_act_request_get_applied_connection(NMActRequest *req);
/*****************************************************************************/
-struct _NMFirewallConfig;
-
-struct _NMFirewallConfig *nm_act_request_get_shared(NMActRequest *req);
-
-void nm_act_request_set_shared(NMActRequest *req, struct _NMFirewallConfig *rules);
-
-/*****************************************************************************/
-
/* Secrets handling */
typedef void (*NMActRequestSecretsFunc)(NMActRequest * req,
diff --git a/src/core/nm-connectivity.c b/src/core/nm-connectivity.c
index a29be6d2aa..524c9cde0b 100644
--- a/src/core/nm-connectivity.c
+++ b/src/core/nm-connectivity.c
@@ -16,6 +16,7 @@
#include <glib-unix.h>
#include "c-list/src/c-list.h"
+#include "libnm-platform/nmp-object.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-config.h"
#include "NetworkManagerUtils.h"
diff --git a/src/core/nm-dhcp-config.c b/src/core/nm-dhcp-config.c
index 1cbad49e2f..62b79c37a3 100644
--- a/src/core/nm-dhcp-config.c
+++ b/src/core/nm-dhcp-config.c
@@ -8,9 +8,11 @@
#include "nm-dhcp-config.h"
#include "nm-dbus-interface.h"
+#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-dbus-object.h"
#include "nm-core-utils.h"
+#include "nm-l3-config-data.h"
/*****************************************************************************/
@@ -49,7 +51,8 @@ static GType nm_dhcp6_config_get_type(void);
NM_GOBJECT_PROPERTIES_DEFINE(NMDhcpConfig, PROP_OPTIONS, );
typedef struct {
- GVariant *options;
+ const NML3ConfigData *l3cd;
+ GVariant * options;
} NMDhcpConfigPrivate;
struct _NMDhcpConfig {
@@ -77,17 +80,41 @@ nm_dhcp_config_get_addr_family(NMDhcpConfig *self)
/*****************************************************************************/
void
-nm_dhcp_config_set_options(NMDhcpConfig *self, GHashTable *options)
+nm_dhcp_config_set_lease(NMDhcpConfig *self, const NML3ConfigData *l3cd)
{
- NMDhcpConfigPrivate *priv;
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd2 = NULL;
+ gs_unref_variant GVariant *options2 = NULL;
+ NMDhcpConfigPrivate * priv;
g_return_if_fail(NM_IS_DHCP_CONFIG(self));
- g_return_if_fail(options);
priv = NM_DHCP_CONFIG_GET_PRIVATE(self);
- nm_g_variant_unref(priv->options);
- priv->options = g_variant_ref_sink(nm_utils_strdict_to_variant_asv(options));
+ if (priv->l3cd == l3cd)
+ return;
+
+ if (l3cd)
+ nm_l3_config_data_ref_and_seal(l3cd);
+ NM_SWAP(&priv->l3cd, &l3cd);
+
+ options2 = NULL;
+ if (priv->l3cd) {
+ NMDhcpLease *lease;
+
+ lease = nm_l3_config_data_get_dhcp_lease(priv->l3cd, nm_dhcp_config_get_addr_family(self));
+ if (lease)
+ options2 = nm_utils_strdict_to_variant_asv(nm_dhcp_lease_get_options(lease));
+ }
+ if (!options2)
+ options2 = nm_g_variant_singleton_aLsvI();
+
+ options2 = g_variant_ref_sink(options2);
+
+ if (g_variant_equal(priv->options, options2))
+ return;
+
+ NM_SWAP(&priv->options, &options2);
+
_notify(self, PROP_OPTIONS);
}
@@ -95,19 +122,22 @@ const char *
nm_dhcp_config_get_option(NMDhcpConfig *self, const char *key)
{
NMDhcpConfigPrivate *priv;
- const char * value;
+ NMDhcpLease * lease;
g_return_val_if_fail(NM_IS_DHCP_CONFIG(self), NULL);
g_return_val_if_fail(key, NULL);
priv = NM_DHCP_CONFIG_GET_PRIVATE(self);
- if (priv->options && g_variant_lookup(priv->options, key, "&s", &value))
- return value;
- else
+ if (!priv->l3cd)
return NULL;
+
+ lease = nm_l3_config_data_get_dhcp_lease(priv->l3cd, nm_dhcp_config_get_addr_family(self));
+ return nm_dhcp_lease_lookup_option(lease, key);
}
+/*****************************************************************************/
+
GVariant *
nm_dhcp_config_get_options(NMDhcpConfig *self)
{
@@ -125,7 +155,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
switch (prop_id) {
case PROP_OPTIONS:
- g_value_set_variant(value, priv->options ?: nm_g_variant_singleton_aLsvI());
+ g_value_set_variant(value, priv->options);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -137,7 +167,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
nm_dhcp_config_init(NMDhcpConfig *self)
-{}
+{
+ NM_DHCP_CONFIG_GET_PRIVATE(self)->options = g_variant_ref(nm_g_variant_singleton_aLsvI());
+}
NMDhcpConfig *
nm_dhcp_config_new(int addr_family)
@@ -154,6 +186,8 @@ finalize(GObject *object)
nm_g_variant_unref(priv->options);
+ nm_l3_config_data_unref(priv->l3cd);
+
G_OBJECT_CLASS(nm_dhcp_config_parent_class)->finalize(object);
}
diff --git a/src/core/nm-dhcp-config.h b/src/core/nm-dhcp-config.h
index 9e68f2fb3a..6fb15ebfa9 100644
--- a/src/core/nm-dhcp-config.h
+++ b/src/core/nm-dhcp-config.h
@@ -27,7 +27,7 @@ NMDhcpConfig *nm_dhcp_config_new(int addr_family);
int nm_dhcp_config_get_addr_family(NMDhcpConfig *self);
-void nm_dhcp_config_set_options(NMDhcpConfig *self, GHashTable *options);
+void nm_dhcp_config_set_lease(NMDhcpConfig *self, const NML3ConfigData *l3cd);
const char *nm_dhcp_config_get_option(NMDhcpConfig *self, const char *option);
diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c
index 32c9db627c..67786125b7 100644
--- a/src/core/nm-dispatcher.c
+++ b/src/core/nm-dispatcher.c
@@ -15,9 +15,7 @@
#include "nm-act-request.h"
#include "devices/nm-device.h"
#include "nm-dhcp-config.h"
-#include "nm-proxy-config.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
+#include "nm-l3-config-data.h"
#include "nm-manager.h"
#include "settings/nm-settings-connection.h"
#include "libnm-platform/nm-platform.h"
@@ -148,50 +146,47 @@ _init_dispatcher(void)
/*****************************************************************************/
static void
-dump_proxy_to_props(NMProxyConfig *proxy, GVariantBuilder *builder)
+dump_proxy_to_props(const NML3ConfigData *l3cd, GVariantBuilder *builder)
{
- const char *pac_url = NULL, *pac_script = NULL;
+ const char *s;
- if (nm_proxy_config_get_method(proxy) == NM_PROXY_CONFIG_METHOD_NONE)
+ if (nm_l3_config_data_get_proxy_method(l3cd) != NM_PROXY_CONFIG_METHOD_AUTO)
return;
- pac_url = nm_proxy_config_get_pac_url(proxy);
- if (pac_url) {
- g_variant_builder_add(builder, "{sv}", "pac-url", g_variant_new_string(pac_url));
- }
+ s = nm_l3_config_data_get_proxy_pac_url(l3cd);
+ if (s)
+ g_variant_builder_add(builder, "{sv}", "pac-url", g_variant_new_string(s));
- pac_script = nm_proxy_config_get_pac_script(proxy);
- if (pac_script) {
- g_variant_builder_add(builder, "{sv}", "pac-script", g_variant_new_string(pac_script));
- }
+ s = nm_l3_config_data_get_proxy_pac_script(l3cd);
+ if (s)
+ g_variant_builder_add(builder, "{sv}", "pac-script", g_variant_new_string(s));
}
static void
-dump_ip_to_props(NMIPConfig *ip, GVariantBuilder *builder)
+dump_ip_to_props(const NML3ConfigData *l3cd, int addr_family, GVariantBuilder *builder)
{
- const int addr_family = nm_ip_config_get_addr_family(ip);
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- const NMPObject *obj;
- GVariantBuilder int_builder;
- NMDedupMultiIter ipconf_iter;
- GVariant * var1;
- GVariant * var2;
- guint n;
- guint i;
- const NMPObject *default_route;
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+ const NMPObject * obj;
+ GVariantBuilder int_builder;
+ NMDedupMultiIter ipconf_iter;
+ GVariant * var1;
+ GVariant * var2;
+ guint n;
+ guint i;
+ const NMPObject * default_route;
+ const char *const *strarr;
+ const in_addr_t * ip4arr;
+ gconstpointer iparr;
if (IS_IPv4)
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aau"));
else
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("a(ayuay)"));
- default_route = nm_ip_config_best_default_route_get(ip);
- if (IS_IPv4)
- nm_ip_config_iter_ip4_address_init(&ipconf_iter, NM_IP4_CONFIG(ip));
- else
- nm_ip_config_iter_ip6_address_init(&ipconf_iter, NM_IP6_CONFIG(ip));
- while (nm_platform_dedup_multi_iter_next_obj(&ipconf_iter,
- &obj,
- NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4))) {
+ default_route = nm_l3_config_data_get_best_default_route(l3cd, addr_family);
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ l3cd,
+ &obj,
+ NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)) {
const NMPlatformIPXAddress *addr = NMP_OBJECT_CAST_IPX_ADDRESS(obj);
if (IS_IPv4) {
@@ -225,30 +220,28 @@ dump_ip_to_props(NMIPConfig *ip, GVariantBuilder *builder)
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au"));
else
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aay"));
- n = nm_ip_config_get_num_nameservers(ip);
+ iparr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &n);
for (i = 0; i < n; i++) {
- if (IS_IPv4) {
- g_variant_builder_add(&int_builder,
- "u",
- nm_ip4_config_get_nameserver(NM_IP4_CONFIG(ip), i));
- } else {
- var1 = nm_g_variant_new_ay_in6addr(nm_ip6_config_get_nameserver(NM_IP6_CONFIG(ip), i));
+ if (IS_IPv4)
+ g_variant_builder_add(&int_builder, "u", ((const in_addr_t *) iparr)[i]);
+ else {
+ var1 = nm_g_variant_new_ay_in6addr(&(((const struct in6_addr *) iparr)[i]));
g_variant_builder_add(&int_builder, "@ay", var1);
}
}
g_variant_builder_add(builder, "{sv}", "nameservers", g_variant_builder_end(&int_builder));
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("as"));
- n = nm_ip_config_get_num_domains(ip);
+ strarr = nm_l3_config_data_get_domains(l3cd, addr_family, &n);
for (i = 0; i < n; i++)
- g_variant_builder_add(&int_builder, "s", nm_ip_config_get_domain(ip, i));
+ g_variant_builder_add(&int_builder, "s", strarr[i]);
g_variant_builder_add(builder, "{sv}", "domains", g_variant_builder_end(&int_builder));
if (IS_IPv4) {
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au"));
- n = nm_ip4_config_get_num_wins(NM_IP4_CONFIG(ip));
+ ip4arr = nm_l3_config_data_get_wins(l3cd, &n);
for (i = 0; i < n; i++)
- g_variant_builder_add(&int_builder, "u", nm_ip4_config_get_wins(NM_IP4_CONFIG(ip), i));
+ g_variant_builder_add(&int_builder, "u", ip4arr[i]);
g_variant_builder_add(builder, "{sv}", "wins-servers", g_variant_builder_end(&int_builder));
}
@@ -256,13 +249,10 @@ dump_ip_to_props(NMIPConfig *ip, GVariantBuilder *builder)
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aau"));
else
g_variant_builder_init(&int_builder, G_VARIANT_TYPE("a(ayuayu)"));
- if (IS_IPv4)
- nm_ip_config_iter_ip4_route_init(&ipconf_iter, NM_IP4_CONFIG(ip));
- else
- nm_ip_config_iter_ip6_route_init(&ipconf_iter, NM_IP6_CONFIG(ip));
- while (nm_platform_dedup_multi_iter_next_obj(&ipconf_iter,
- &obj,
- NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4))) {
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ l3cd,
+ &obj,
+ NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) {
const NMPlatformIPXRoute *route = NMP_OBJECT_CAST_IPX_ROUTE(obj);
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route))
@@ -299,10 +289,8 @@ fill_device_props(NMDevice * device,
GVariant ** dhcp4_props,
GVariant ** dhcp6_props)
{
- NMProxyConfig *proxy_config;
- NMIP4Config * ip4_config;
- NMIP6Config * ip6_config;
- NMDhcpConfig * dhcp_config;
+ const NML3ConfigData *l3cd;
+ NMDhcpConfig * dhcp_config;
/* If the action is for a VPN, send the VPN's IP interface instead of the device's */
g_variant_builder_add(dev_builder,
@@ -329,17 +317,12 @@ fill_device_props(NMDevice * device,
g_variant_new_object_path(nm_dbus_object_get_path(NM_DBUS_OBJECT(device))));
}
- proxy_config = nm_device_get_proxy_config(device);
- if (proxy_config)
- dump_proxy_to_props(proxy_config, proxy_builder);
-
- ip4_config = nm_device_get_ip4_config(device);
- if (ip4_config)
- dump_ip_to_props(NM_IP_CONFIG(ip4_config), ip4_builder);
-
- ip6_config = nm_device_get_ip6_config(device);
- if (ip6_config)
- dump_ip_to_props(NM_IP_CONFIG(ip6_config), ip6_builder);
+ l3cd = nm_device_get_l3cd(device, TRUE);
+ if (l3cd) {
+ dump_ip_to_props(l3cd, AF_INET, ip4_builder);
+ dump_ip_to_props(l3cd, AF_INET6, ip6_builder);
+ dump_proxy_to_props(l3cd, proxy_builder);
+ }
dhcp_config = nm_device_get_dhcp_config(device, AF_INET);
if (dhcp_config)
@@ -351,19 +334,16 @@ fill_device_props(NMDevice * device,
}
static void
-fill_vpn_props(NMProxyConfig * proxy_config,
- NMIP4Config * ip4_config,
- NMIP6Config * ip6_config,
- GVariantBuilder *proxy_builder,
- GVariantBuilder *ip4_builder,
- GVariantBuilder *ip6_builder)
+fill_vpn_props(const NML3ConfigData *l3cd,
+ GVariantBuilder * proxy_builder,
+ GVariantBuilder * ip4_builder,
+ GVariantBuilder * ip6_builder)
{
- if (proxy_config)
- dump_proxy_to_props(proxy_config, proxy_builder);
- if (ip4_config)
- dump_ip_to_props(NM_IP_CONFIG(ip4_config), ip4_builder);
- if (ip6_config)
- dump_ip_to_props(NM_IP_CONFIG(ip6_config), ip6_builder);
+ if (l3cd) {
+ dump_ip_to_props(l3cd, AF_INET, ip4_builder);
+ dump_ip_to_props(l3cd, AF_INET6, ip6_builder);
+ dump_proxy_to_props(l3cd, proxy_builder);
+ }
}
static const char *
@@ -479,9 +459,7 @@ _dispatcher_call(NMDispatcherAction action,
gboolean activation_type_external,
NMConnectivityState connectivity_state,
const char * vpn_iface,
- NMProxyConfig * vpn_proxy_config,
- NMIP4Config * vpn_ip4_config,
- NMIP6Config * vpn_ip6_config,
+ const NML3ConfigData *l3cd,
NMDispatcherFunc callback,
gpointer user_data,
NMDispatcherCallId ** out_call_id)
@@ -593,10 +571,8 @@ _dispatcher_call(NMDispatcherAction action,
&device_ip6_props,
&device_dhcp4_props,
&device_dhcp6_props);
- if (vpn_ip4_config || vpn_ip6_config) {
- fill_vpn_props(vpn_proxy_config,
- vpn_ip4_config,
- vpn_ip6_config,
+ if (l3cd) {
+ fill_vpn_props(l3cd,
&vpn_proxy_props,
&vpn_ip4_props,
&vpn_ip6_props);
@@ -693,8 +669,6 @@ nm_dispatcher_call_hostname(NMDispatcherFunc callback,
NM_CONNECTIVITY_UNKNOWN,
NULL,
NULL,
- NULL,
- NULL,
callback,
user_data,
out_call_id);
@@ -744,8 +718,6 @@ nm_dispatcher_call_device(NMDispatcherAction action,
NM_CONNECTIVITY_UNKNOWN,
NULL,
NULL,
- NULL,
- NULL,
callback,
user_data,
out_call_id);
@@ -790,8 +762,6 @@ nm_dispatcher_call_device_sync(NMDispatcherAction action,
NULL,
NULL,
NULL,
- NULL,
- NULL,
NULL);
}
@@ -802,9 +772,7 @@ nm_dispatcher_call_device_sync(NMDispatcherAction action,
* @applied_connection: the currently applied connection
* @parent_device: the parent #NMDevice of the VPN connection
* @vpn_iface: the IP interface of the VPN tunnel, if any
- * @vpn_proxy_config: the #NMProxyConfig of the VPN connection
- * @vpn_ip4_config: the #NMIP4Config of the VPN connection
- * @vpn_ip6_config: the #NMIP6Config of the VPN connection
+ * @vpn_l3cd: the #NML3ConfigData of the VPN connection
* @callback: a caller-supplied callback to execute when done
* @user_data: caller-supplied pointer passed to @callback
* @out_call_id: on success, a call identifier which can be passed to
@@ -821,9 +789,7 @@ nm_dispatcher_call_vpn(NMDispatcherAction action,
NMConnection * applied_connection,
NMDevice * parent_device,
const char * vpn_iface,
- NMProxyConfig * vpn_proxy_config,
- NMIP4Config * vpn_ip4_config,
- NMIP6Config * vpn_ip6_config,
+ const NML3ConfigData *l3cd,
NMDispatcherFunc callback,
gpointer user_data,
NMDispatcherCallId ** out_call_id)
@@ -836,9 +802,7 @@ nm_dispatcher_call_vpn(NMDispatcherAction action,
FALSE,
NM_CONNECTIVITY_UNKNOWN,
vpn_iface,
- vpn_proxy_config,
- vpn_ip4_config,
- vpn_ip6_config,
+ l3cd,
callback,
user_data,
out_call_id);
@@ -851,9 +815,7 @@ nm_dispatcher_call_vpn(NMDispatcherAction action,
* @applied_connection: the currently applied connection
* @parent_device: the parent #NMDevice of the VPN connection
* @vpn_iface: the IP interface of the VPN tunnel, if any
- * @vpn_proxy_config: the #NMProxyConfig of the VPN connection
- * @vpn_ip4_config: the #NMIP4Config of the VPN connection
- * @vpn_ip6_config: the #NMIP6Config of the VPN connection
+ * @vpn_l3cd: the #NML3ConfigData of the VPN connection
*
* This method always invokes the dispatcher action synchronously and it may
* take a long time to return.
@@ -866,9 +828,7 @@ nm_dispatcher_call_vpn_sync(NMDispatcherAction action,
NMConnection * applied_connection,
NMDevice * parent_device,
const char * vpn_iface,
- NMProxyConfig * vpn_proxy_config,
- NMIP4Config * vpn_ip4_config,
- NMIP6Config * vpn_ip6_config)
+ const NML3ConfigData *l3cd)
{
return _dispatcher_call(action,
TRUE,
@@ -878,9 +838,7 @@ nm_dispatcher_call_vpn_sync(NMDispatcherAction action,
FALSE,
NM_CONNECTIVITY_UNKNOWN,
vpn_iface,
- vpn_proxy_config,
- vpn_ip4_config,
- vpn_ip6_config,
+ l3cd,
NULL,
NULL,
NULL);
@@ -913,8 +871,6 @@ nm_dispatcher_call_connectivity(NMConnectivityState connectivity_state,
connectivity_state,
NULL,
NULL,
- NULL,
- NULL,
callback,
user_data,
out_call_id);
diff --git a/src/core/nm-dispatcher.h b/src/core/nm-dispatcher.h
index d588de4e8f..4598a56136 100644
--- a/src/core/nm-dispatcher.h
+++ b/src/core/nm-dispatcher.h
@@ -48,9 +48,7 @@ gboolean nm_dispatcher_call_vpn(NMDispatcherAction action,
NMConnection * applied_connection,
NMDevice * parent_device,
const char * vpn_iface,
- NMProxyConfig * vpn_proxy_config,
- NMIP4Config * vpn_ip4_config,
- NMIP6Config * vpn_ip6_config,
+ const NML3ConfigData *l3cd,
NMDispatcherFunc callback,
gpointer user_data,
NMDispatcherCallId ** out_call_id);
@@ -60,9 +58,7 @@ gboolean nm_dispatcher_call_vpn_sync(NMDispatcherAction action,
NMConnection * applied_connection,
NMDevice * parent_device,
const char * vpn_iface,
- NMProxyConfig * vpn_proxy_config,
- NMIP4Config * vpn_ip4_config,
- NMIP6Config * vpn_ip6_config);
+ const NML3ConfigData *l3cd);
gboolean nm_dispatcher_call_connectivity(NMConnectivityState state,
NMDispatcherFunc callback,
diff --git a/src/core/nm-iface-helper.c b/src/core/nm-iface-helper.c
index 296bf091ee..2e12165e33 100644
--- a/src/core/nm-iface-helper.c
+++ b/src/core/nm-iface-helper.c
@@ -90,19 +90,24 @@ static struct {
NULL, \
"iface-helper: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) _NM_UTILS_MACRO_REST(__VA_ARGS__))
+//XXX
+#if 0
+
/*****************************************************************************/
static void
-dhcp4_state_changed(NMDhcpClient *client,
- NMDhcpState state,
- NMIP4Config * ip4_config,
- GHashTable * options,
- gpointer user_data)
+dhcp4_state_changed(NMDhcpClient * client,
+ NMDhcpState state,
+ NML3ConfigData *l3cfg,
+ gpointer user_data)
{
static NMIP4Config *last_config = NULL;
NMIP4Config * existing;
gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
gs_free_error GError *error = NULL;
+ NMIP4Config * ip4_config = NULL; //XXX
+
+ /* FIXME(l3cfg): fix handling metric_any/table_any for routes. */
g_return_if_fail(!ip4_config || NM_IS_IP4_CONFIG(ip4_config));
@@ -512,10 +517,13 @@ ip6_address_changed(NMPlatform * platform,
data,
nm_g_slice_free_fcn(DadFailedHandleData));
}
+#endif
int
main(int argc, char *argv[])
{
+//XXX
+#if 0
char * bad_domains = NULL;
gs_free_error GError *error = NULL;
gboolean wrote_pidfile = FALSE;
@@ -666,8 +674,6 @@ main(int argc, char *argv[])
hwaddr,
bcast_hwaddr,
global_opt.uuid,
- RT_TABLE_MAIN,
- global_opt.priority_v4,
NM_DHCP_CLIENT_FLAGS_NONE,
!!global_opt.dhcp4_hostname,
global_opt.dhcp4_hostname,
@@ -763,6 +769,7 @@ main(int argc, char *argv[])
nm_clear_g_source(&sd_id);
nm_clear_pointer(&gl.main_loop, g_main_loop_unref);
+#endif
return 0;
}
@@ -855,5 +862,6 @@ nm_device_get_type(void)
GType
nm_active_connection_get_type(void)
{
+ (void) gl; //XXX
g_return_val_if_reached(0);
}
diff --git a/src/core/nm-ip-config.c b/src/core/nm-ip-config.c
index 2426eb4941..f0a93cc4d2 100644
--- a/src/core/nm-ip-config.c
+++ b/src/core/nm-ip-config.c
@@ -12,26 +12,29 @@
/*****************************************************************************/
-NM_GOBJECT_PROPERTIES_DEFINE(NMIPConfig, PROP_L3CFG, PROP_IS_VPN, );
+GType nm_ip4_config_get_type(void);
+GType nm_ip6_config_get_type(void);
-typedef struct _NMIPConfigPrivate {
- NML3Cfg *l3cfg;
- bool is_vpn : 1;
-} NMIPConfigPrivate;
+/*****************************************************************************/
+
+typedef struct _NMIPConfigPrivate NMIPConfigPrivate;
+
+NM_GOBJECT_PROPERTIES_DEFINE_FULL(_ip, NMIPConfig, PROP_IP_L3CFG, PROP_IP_IS_VPN, );
G_DEFINE_ABSTRACT_TYPE(NMIPConfig, nm_ip_config, NM_TYPE_DBUS_OBJECT)
-#define NM_IP_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMIPConfig, NM_IS_IP_CONFIG)
+#define NM_IP_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIPConfig, NM_IS_IP_CONFIG)
/*****************************************************************************/
static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+get_property_ip(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
NMIPConfig * self = NM_IP_CONFIG(object);
NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
- (void) priv;
+ (void) priv; //XXX
+
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -44,14 +47,16 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
{
NMIPConfig * self = NM_IP_CONFIG(object);
NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
+ gpointer ptr;
switch (prop_id) {
- case PROP_L3CFG:
+ case PROP_IP_L3CFG:
/* construct-only */
- priv->l3cfg = nm_g_object_ref(g_value_get_pointer(value));
- nm_assert(!priv->l3cfg || NM_IS_L3CFG(priv->l3cfg));
+ ptr = g_value_get_pointer(value);
+ nm_assert(NM_IS_L3CFG(ptr));
+ priv->l3cfg = g_object_ref(ptr);
break;
- case PROP_IS_VPN:
+ case PROP_IP_IS_VPN:
/* construct-only */
priv->is_vpn = g_value_get_boolean(value);
break;
@@ -65,13 +70,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
static void
nm_ip_config_init(NMIPConfig *self)
-{
- NMIPConfigPrivate *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_IP_CONFIG, NMIPConfigPrivate);
-
- self->_priv = priv;
-}
+{}
NMIPConfig *
nm_ip_config_new(int addr_family, NML3Cfg *l3cfg, gboolean is_vpn)
@@ -88,13 +87,25 @@ nm_ip_config_new(int addr_family, NML3Cfg *l3cfg, gboolean is_vpn)
NULL);
}
+void
+nm_ip_config_take_and_unexport_on_idle(NMIPConfig *self_take)
+{
+ if (!self_take)
+ return;
+
+ //XXX: freeze the instance so that no more signals are emitted while
+ // the instance gets unexported.
+
+ nm_dbus_object_unexport_on_idle(g_steal_pointer(&self_take));
+}
+
static void
finalize(GObject *object)
{
NMIPConfig * self = NM_IP_CONFIG(object);
NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
- nm_g_object_unref(priv->l3cfg);
+ g_object_unref(priv->l3cfg);
G_OBJECT_CLASS(nm_ip_config_parent_class)->finalize(object);
}
@@ -102,26 +113,420 @@ finalize(GObject *object)
static void
nm_ip_config_class_init(NMIPConfigClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- g_type_class_add_private(object_class, sizeof(NMIPConfigPrivate));
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
+ NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
- object_class->get_property = get_property;
+ object_class->get_property = get_property_ip;
object_class->set_property = set_property;
object_class->finalize = finalize;
- obj_properties[PROP_L3CFG] =
+ dbus_object_class->export_on_construction = TRUE;
+
+ obj_properties_ip[PROP_IP_L3CFG] =
g_param_spec_pointer(NM_IP_CONFIG_L3CFG,
"",
"",
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_IS_VPN] =
+ obj_properties_ip[PROP_IP_IS_VPN] =
g_param_spec_boolean(NM_IP_CONFIG_IS_VPN,
"",
"",
FALSE,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST_ip, obj_properties_ip);
+}
+
+/*****************************************************************************/
+
+/* public*/
+#define NM_IP4_CONFIG_ADDRESS_DATA "address-data"
+#define NM_IP4_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_IP4_CONFIG_DNS_PRIORITY "dns-priority"
+#define NM_IP4_CONFIG_DOMAINS "domains"
+#define NM_IP4_CONFIG_GATEWAY "gateway"
+#define NM_IP4_CONFIG_NAMESERVER_DATA "nameserver-data"
+#define NM_IP4_CONFIG_ROUTE_DATA "route-data"
+#define NM_IP4_CONFIG_SEARCHES "searches"
+#define NM_IP4_CONFIG_WINS_SERVER_DATA "wins-server-data"
+
+/* deprecated */
+#define NM_IP4_CONFIG_ADDRESSES "addresses"
+#define NM_IP4_CONFIG_NAMESERVERS "nameservers"
+#define NM_IP4_CONFIG_ROUTES "routes"
+#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers"
+
+typedef struct _NMIP4Config NMIP4Config;
+typedef struct _NMIP4ConfigClass NMIP4ConfigClass;
+
+NM_GOBJECT_PROPERTIES_DEFINE_FULL(_ip4,
+ NMIP4Config,
+ PROP_IP4_ADDRESSES,
+ PROP_IP4_ADDRESS_DATA,
+ PROP_IP4_DNS_OPTIONS,
+ PROP_IP4_DNS_PRIORITY,
+ PROP_IP4_DOMAINS,
+ PROP_IP4_GATEWAY,
+ PROP_IP4_NAMESERVERS,
+ PROP_IP4_NAMESERVER_DATA,
+ PROP_IP4_ROUTES,
+ PROP_IP4_ROUTE_DATA,
+ PROP_IP4_SEARCHES,
+ PROP_IP4_WINS_SERVERS,
+ PROP_IP4_WINS_SERVER_DATA, );
+
+struct _NMIP4Config {
+ NMIPConfig parent;
+};
+
+struct _NMIP4ConfigClass {
+ NMIPConfigClass parent;
+};
+
+G_DEFINE_TYPE(NMIP4Config, nm_ip4_config, NM_TYPE_IP_CONFIG)
+
+static void
+get_property_ip4(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ NMIPConfig * self = NM_IP_CONFIG(object);
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
+
+ (void) priv; //XXX
+
+ switch (prop_id) {
+ default:
+ return; //XXX
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static const NMDBusInterfaceInfoExtended interface_info_ip4_config = {
+ .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
+ NM_DBUS_INTERFACE_IP4_CONFIG,
+ .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Addresses",
+ "aau",
+ NM_IP4_CONFIG_ADDRESSES),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AddressData",
+ "aa{sv}",
+ NM_IP4_CONFIG_ADDRESS_DATA),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Gateway", "s", NM_IP4_CONFIG_GATEWAY),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Routes", "aau", NM_IP4_CONFIG_ROUTES),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RouteData",
+ "aa{sv}",
+ NM_IP4_CONFIG_ROUTE_DATA),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NameserverData",
+ "aa{sv}",
+ NM_IP4_CONFIG_NAMESERVER_DATA),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Nameservers",
+ "au",
+ NM_IP4_CONFIG_NAMESERVERS),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Domains", "as", NM_IP4_CONFIG_DOMAINS),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Searches",
+ "as",
+ NM_IP4_CONFIG_SEARCHES),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsOptions",
+ "as",
+ NM_IP4_CONFIG_DNS_OPTIONS),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsPriority",
+ "i",
+ NM_IP4_CONFIG_DNS_PRIORITY),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WinsServerData",
+ "as",
+ NM_IP4_CONFIG_WINS_SERVER_DATA),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WinsServers",
+ "au",
+ NM_IP4_CONFIG_WINS_SERVERS), ), ),
+};
+
+static void
+nm_ip4_config_init(NMIP4Config *self)
+{}
+
+static void
+nm_ip4_config_class_init(NMIP4ConfigClass *klass)
+{
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
+ NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
+ NMIPConfigClass * ip_config_class = NM_IP_CONFIG_CLASS(klass);
+
+ ip_config_class->addr_family = AF_INET;
+
+ dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/IP4Config");
+ dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_ip4_config);
+
+ object_class->get_property = get_property_ip4;
+
+ obj_properties_ip4[PROP_IP4_ADDRESS_DATA] =
+ g_param_spec_variant(NM_IP4_CONFIG_ADDRESS_DATA,
+ "",
+ "",
+ G_VARIANT_TYPE("aa{sv}"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_ADDRESSES] =
+ g_param_spec_variant(NM_IP4_CONFIG_ADDRESSES,
+ "",
+ "",
+ G_VARIANT_TYPE("aau"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_ROUTE_DATA] =
+ g_param_spec_variant(NM_IP4_CONFIG_ROUTE_DATA,
+ "",
+ "",
+ G_VARIANT_TYPE("aa{sv}"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_ROUTES] =
+ g_param_spec_variant(NM_IP4_CONFIG_ROUTES,
+ "",
+ "",
+ G_VARIANT_TYPE("aau"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_GATEWAY] =
+ g_param_spec_string(NM_IP4_CONFIG_GATEWAY,
+ "",
+ "",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_NAMESERVER_DATA] =
+ g_param_spec_variant(NM_IP4_CONFIG_NAMESERVER_DATA,
+ "",
+ "",
+ G_VARIANT_TYPE("aa{sv}"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_NAMESERVERS] =
+ g_param_spec_variant(NM_IP4_CONFIG_NAMESERVERS,
+ "",
+ "",
+ G_VARIANT_TYPE("au"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_DOMAINS] =
+ g_param_spec_boxed(NM_IP4_CONFIG_DOMAINS,
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_SEARCHES] =
+ g_param_spec_boxed(NM_IP4_CONFIG_SEARCHES,
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_DNS_OPTIONS] =
+ g_param_spec_boxed(NM_IP4_CONFIG_DNS_OPTIONS,
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_DNS_PRIORITY] =
+ g_param_spec_int(NM_IP4_CONFIG_DNS_PRIORITY,
+ "",
+ "",
+ G_MININT32,
+ G_MAXINT32,
+ 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_WINS_SERVER_DATA] =
+ g_param_spec_variant(NM_IP4_CONFIG_WINS_SERVER_DATA,
+ "",
+ "",
+ G_VARIANT_TYPE("as"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip4[PROP_IP4_WINS_SERVERS] =
+ g_param_spec_variant(NM_IP4_CONFIG_WINS_SERVERS,
+ "",
+ "",
+ G_VARIANT_TYPE("au"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST_ip4, obj_properties_ip4);
+}
+
+/*****************************************************************************/
+
+/* public */
+#define NM_IP6_CONFIG_ADDRESS_DATA "address-data"
+#define NM_IP6_CONFIG_ROUTE_DATA "route-data"
+#define NM_IP6_CONFIG_GATEWAY "gateway"
+#define NM_IP6_CONFIG_NAMESERVERS "nameservers"
+#define NM_IP6_CONFIG_DOMAINS "domains"
+#define NM_IP6_CONFIG_SEARCHES "searches"
+#define NM_IP6_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_IP6_CONFIG_DNS_PRIORITY "dns-priority"
+
+/* deprecated */
+#define NM_IP6_CONFIG_ADDRESSES "addresses"
+#define NM_IP6_CONFIG_ROUTES "routes"
+
+typedef struct _NMIP6Config NMIP6Config;
+typedef struct _NMIP6ConfigClass NMIP6ConfigClass;
+
+NM_GOBJECT_PROPERTIES_DEFINE_FULL(_ip6,
+ NMIP6Config,
+ PROP_IP6_ADDRESS_DATA,
+ PROP_IP6_ROUTE_DATA,
+ PROP_IP6_GATEWAY,
+ PROP_IP6_NAMESERVERS,
+ PROP_IP6_DOMAINS,
+ PROP_IP6_SEARCHES,
+ PROP_IP6_DNS_OPTIONS,
+ PROP_IP6_DNS_PRIORITY,
+ PROP_IP6_ADDRESSES,
+ PROP_IP6_ROUTES, );
+
+struct _NMIP6Config {
+ NMIPConfig parent;
+};
+
+struct _NMIP6ConfigClass {
+ NMIPConfigClass parent;
+};
+
+G_DEFINE_TYPE(NMIP6Config, nm_ip6_config, NM_TYPE_IP_CONFIG)
+
+static const NMDBusInterfaceInfoExtended interface_info_ip6_config = {
+ .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
+ NM_DBUS_INTERFACE_IP6_CONFIG,
+ .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Addresses",
+ "a(ayuay)",
+ NM_IP6_CONFIG_ADDRESSES),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AddressData",
+ "aa{sv}",
+ NM_IP6_CONFIG_ADDRESS_DATA),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Gateway", "s", NM_IP6_CONFIG_GATEWAY),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Routes",
+ "a(ayuayu)",
+ NM_IP6_CONFIG_ROUTES),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RouteData",
+ "aa{sv}",
+ NM_IP6_CONFIG_ROUTE_DATA),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Nameservers",
+ "aay",
+ NM_IP6_CONFIG_NAMESERVERS),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Domains", "as", NM_IP6_CONFIG_DOMAINS),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Searches",
+ "as",
+ NM_IP6_CONFIG_SEARCHES),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsOptions",
+ "as",
+ NM_IP6_CONFIG_DNS_OPTIONS),
+ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsPriority",
+ "i",
+ NM_IP6_CONFIG_DNS_PRIORITY), ), ),
+};
+
+static void
+get_property_ip6(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ NMIPConfig * self = NM_IP_CONFIG(object);
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
+
+ (void) priv; //XXX
+
+ switch (prop_id) {
+ //XXX
+ default:
+ return; //XXX
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_ip6_config_init(NMIP6Config *self)
+{}
+
+static void
+nm_ip6_config_class_init(NMIP6ConfigClass *klass)
+{
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
+ NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
+ NMIPConfigClass * ip_config_class = NM_IP_CONFIG_CLASS(klass);
+
+ ip_config_class->addr_family = AF_INET6;
+
+ dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/IP6Config");
+ dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_ip6_config);
+
+ object_class->get_property = get_property_ip6;
+
+ obj_properties_ip6[PROP_IP6_ADDRESS_DATA] =
+ g_param_spec_variant(NM_IP6_CONFIG_ADDRESS_DATA,
+ "",
+ "",
+ G_VARIANT_TYPE("aa{sv}"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_ADDRESSES] =
+ g_param_spec_variant(NM_IP6_CONFIG_ADDRESSES,
+ "",
+ "",
+ G_VARIANT_TYPE("a(ayuay)"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_ROUTE_DATA] =
+ g_param_spec_variant(NM_IP6_CONFIG_ROUTE_DATA,
+ "",
+ "",
+ G_VARIANT_TYPE("aa{sv}"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_ROUTES] =
+ g_param_spec_variant(NM_IP6_CONFIG_ROUTES,
+ "",
+ "",
+ G_VARIANT_TYPE("a(ayuayu)"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_GATEWAY] =
+ g_param_spec_string(NM_IP6_CONFIG_GATEWAY,
+ "",
+ "",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_NAMESERVERS] =
+ g_param_spec_variant(NM_IP6_CONFIG_NAMESERVERS,
+ "",
+ "",
+ G_VARIANT_TYPE("aay"),
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_DOMAINS] =
+ g_param_spec_boxed(NM_IP6_CONFIG_DOMAINS,
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_SEARCHES] =
+ g_param_spec_boxed(NM_IP6_CONFIG_SEARCHES,
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_DNS_OPTIONS] =
+ g_param_spec_boxed(NM_IP6_CONFIG_DNS_OPTIONS,
+ "",
+ "",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_properties_ip6[PROP_IP6_DNS_PRIORITY] =
+ g_param_spec_int(NM_IP6_CONFIG_DNS_PRIORITY,
+ "",
+ "",
+ G_MININT32,
+ G_MAXINT32,
+ 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST_ip6, obj_properties_ip6);
}
diff --git a/src/core/nm-ip-config.h b/src/core/nm-ip-config.h
index 8e1a593412..6e4022b5e0 100644
--- a/src/core/nm-ip-config.h
+++ b/src/core/nm-ip-config.h
@@ -7,6 +7,7 @@
#define __NM_IP_CONFIG_H__
#include "nm-dbus-object.h"
+#include "nm-l3cfg.h"
/*****************************************************************************/
@@ -22,23 +23,55 @@
#define NM_IP_CONFIG_L3CFG "l3cfg"
#define NM_IP_CONFIG_IS_VPN "is-vpn"
-struct _NMIPConfigPrivate;
+struct _NMIPConfigPrivate {
+ NML3Cfg *l3cfg;
+ bool is_vpn : 1;
+};
struct _NMIPConfig {
- NMDBusObject parent;
- struct _NMIPConfigPrivate *_priv;
+ NMDBusObject parent;
+ struct _NMIPConfigPrivate _priv;
};
typedef struct {
NMDBusObjectClass parent;
- gboolean is_ipv4;
int addr_family;
} NMIPConfigClass;
GType nm_ip_config_get_type(void);
-GType nm_ip4_config_get_type(void);
-GType nm_ip6_config_get_type(void);
NMIPConfig *nm_ip_config_new(int addr_family, NML3Cfg *l3cfg, gboolean is_vpn);
+void nm_ip_config_take_and_unexport_on_idle(NMIPConfig *self_take);
+
+/*****************************************************************************/
+
+static inline NML3Cfg *
+nm_ip_config_get_l3cfg(NMIPConfig *self)
+{
+ g_return_val_if_fail(NM_IS_IP_CONFIG(self), NULL);
+
+ return self->_priv.l3cfg;
+}
+
+static inline struct _NMDedupMultiIndex *
+nm_ip_config_get_multi_index(NMIPConfig *self)
+{
+ return nm_l3cfg_get_multi_idx(nm_ip_config_get_l3cfg(self));
+}
+
+static inline int
+nm_ip_config_get_ifindex(NMIPConfig *self)
+{
+ return nm_l3cfg_get_ifindex(nm_ip_config_get_l3cfg(self));
+}
+
+static inline int
+nm_ip_config_get_addr_family(NMIPConfig *self)
+{
+ g_return_val_if_fail(NM_IS_IP_CONFIG(self), AF_UNSPEC);
+
+ return NM_IP_CONFIG_GET_CLASS(self)->addr_family;
+}
+
#endif /* __NM_IP_CONFIG_H__ */
diff --git a/src/core/nm-ip4-config.c b/src/core/nm-ip4-config.c
deleted file mode 100644
index 171ed4bae1..0000000000
--- a/src/core/nm-ip4-config.c
+++ /dev/null
@@ -1,3297 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2005 - 2017 Red Hat, Inc.
- * Copyright (C) 2006 - 2008 Novell, Inc.
- */
-
-#include "src/core/nm-default-daemon.h"
-
-#include "nm-ip4-config.h"
-
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <linux/rtnetlink.h>
-
-#include "libnm-glib-aux/nm-dedup-multi.h"
-
-#include "nm-utils.h"
-#include "libnm-platform/nmp-object.h"
-#include "libnm-platform/nm-platform.h"
-#include "libnm-platform/nm-platform-utils.h"
-#include "NetworkManagerUtils.h"
-#include "libnm-core-intern/nm-core-internal.h"
-#include "nm-dbus-object.h"
-
-/*****************************************************************************/
-
-/* internal guint32 are assigned to gobject properties of type uint. Ensure, that uint is large enough */
-G_STATIC_ASSERT(sizeof(uint) >= sizeof(guint32));
-G_STATIC_ASSERT(G_MAXUINT >= 0xFFFFFFFF);
-
-/*****************************************************************************/
-
-static gboolean
-_route_valid(const NMPlatformIP4Route *r)
-{
- return r && r->plen <= 32
- && r->network == nm_utils_ip4_address_clear_host_address(r->network, r->plen);
-}
-
-/*****************************************************************************/
-
-static void
-_idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type,
- const NMDedupMultiObj * obj,
- NMHashState * h)
-{
- nmp_object_id_hash_update((NMPObject *) obj, h);
-}
-
-static gboolean
-_idx_obj_id_equal(const NMDedupMultiIdxType *idx_type,
- const NMDedupMultiObj * obj_a,
- const NMDedupMultiObj * obj_b)
-{
- return nmp_object_id_equal((NMPObject *) obj_a, (NMPObject *) obj_b);
-}
-
-void
-nm_ip_config_dedup_multi_idx_type_init(NMIPConfigDedupMultiIdxType *idx_type,
- NMPObjectType obj_type)
-{
- static const NMDedupMultiIdxTypeClass idx_type_class = {
- .idx_obj_id_hash_update = _idx_obj_id_hash_update,
- .idx_obj_id_equal = _idx_obj_id_equal,
- };
-
- nm_dedup_multi_idx_type_init((NMDedupMultiIdxType *) idx_type, &idx_type_class);
- idx_type->obj_type = obj_type;
-}
-
-/*****************************************************************************/
-
-gboolean
-_nm_ip_config_add_obj(NMDedupMultiIndex * multi_idx,
- NMIPConfigDedupMultiIdxType *idx_type,
- int ifindex,
- const NMPObject * obj_new,
- const NMPlatformObject * pl_new,
- gboolean merge,
- gboolean append_force,
- const NMPObject ** out_obj_old /* returns a reference! */,
- const NMPObject ** out_obj_new /* does not return a reference */)
-{
- NMPObject obj_new_stackinit;
- const NMDedupMultiEntry *entry_old;
- const NMDedupMultiEntry *entry_new;
-
- nm_assert(multi_idx);
- nm_assert(idx_type);
- nm_assert(NM_IN_SET(idx_type->obj_type,
- NMP_OBJECT_TYPE_IP4_ADDRESS,
- NMP_OBJECT_TYPE_IP4_ROUTE,
- NMP_OBJECT_TYPE_IP6_ADDRESS,
- NMP_OBJECT_TYPE_IP6_ROUTE));
- nm_assert(ifindex > 0);
-
- /* we go through extra lengths to accept a full obj_new object. That one,
- * can be reused by increasing the ref-count. */
- if (!obj_new) {
- nm_assert(pl_new);
- obj_new = nmp_object_stackinit(&obj_new_stackinit, idx_type->obj_type, pl_new);
- NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(&obj_new_stackinit)->ifindex = ifindex;
- } else {
- nm_assert(!pl_new);
- nm_assert(NMP_OBJECT_GET_TYPE(obj_new) == idx_type->obj_type);
- if (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_new)->ifindex != ifindex) {
- obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
- NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(&obj_new_stackinit)->ifindex = ifindex;
- }
- }
- nm_assert(NMP_OBJECT_GET_TYPE(obj_new) == idx_type->obj_type);
- nm_assert(nmp_object_is_alive(obj_new));
-
- entry_old = nm_dedup_multi_index_lookup_obj(multi_idx, &idx_type->parent, obj_new);
-
- if (entry_old) {
- gboolean modified = FALSE;
- const NMPObject *obj_old = entry_old->obj;
-
- if (nmp_object_equal(obj_new, obj_old)) {
- nm_dedup_multi_entry_set_dirty(entry_old, FALSE);
- goto append_force_and_out;
- }
-
- /* if @merge, we merge the new object with the existing one.
- * Otherwise, we replace it entirely. */
- if (merge) {
- switch (idx_type->obj_type) {
- case NMP_OBJECT_TYPE_IP4_ADDRESS:
- case NMP_OBJECT_TYPE_IP6_ADDRESS:
- /* for addresses that we read from the kernel, we keep the timestamps as defined
- * by the previous source (item_old). The reason is, that the other source configured the lifetimes
- * with "what should be" and the kernel values are "what turned out after configuring it".
- *
- * For other sources, the longer lifetime wins. */
- if ((obj_new->ip_address.addr_source == NM_IP_CONFIG_SOURCE_KERNEL
- && obj_old->ip_address.addr_source != NM_IP_CONFIG_SOURCE_KERNEL)
- || nm_platform_ip_address_cmp_expiry(NMP_OBJECT_CAST_IP_ADDRESS(obj_old),
- NMP_OBJECT_CAST_IP_ADDRESS(obj_new))
- > 0) {
- obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
- obj_new_stackinit.ip_address.timestamp =
- NMP_OBJECT_CAST_IP_ADDRESS(obj_old)->timestamp;
- obj_new_stackinit.ip_address.lifetime =
- NMP_OBJECT_CAST_IP_ADDRESS(obj_old)->lifetime;
- obj_new_stackinit.ip_address.preferred =
- NMP_OBJECT_CAST_IP_ADDRESS(obj_old)->preferred;
- modified = TRUE;
- }
-
- /* keep the maximum addr_source. */
- if (obj_new->ip_address.addr_source < obj_old->ip_address.addr_source) {
- obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
- obj_new_stackinit.ip_address.addr_source = obj_old->ip_address.addr_source;
- modified = TRUE;
- }
- break;
- case NMP_OBJECT_TYPE_IP4_ROUTE:
- case NMP_OBJECT_TYPE_IP6_ROUTE:
- /* keep the maximum rt_source. */
- if (obj_new->ip_route.rt_source < obj_old->ip_route.rt_source) {
- obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
- obj_new_stackinit.ip_route.rt_source = obj_old->ip_route.rt_source;
- modified = TRUE;
- }
- break;
- default:
- nm_assert_not_reached();
- break;
- }
-
- if (modified && nmp_object_equal(obj_new, obj_old)) {
- nm_dedup_multi_entry_set_dirty(entry_old, FALSE);
- goto append_force_and_out;
- }
- }
- }
-
- if (!nm_dedup_multi_index_add_full(multi_idx,
- &idx_type->parent,
- obj_new,
- append_force ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE
- : NM_DEDUP_MULTI_IDX_MODE_APPEND,
- NULL,
- entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING,
- NULL,
- &entry_new,
- out_obj_old)) {
- nm_assert_not_reached();
- NM_SET_OUT(out_obj_new, NULL);
- return FALSE;
- }
-
- NM_SET_OUT(out_obj_new, entry_new->obj);
- return TRUE;
-
-append_force_and_out:
- NM_SET_OUT(out_obj_old, nmp_object_ref(entry_old->obj));
- NM_SET_OUT(out_obj_new, entry_old->obj);
- if (append_force) {
- if (nm_dedup_multi_entry_reorder(entry_old, NULL, TRUE))
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * _nm_ip_config_lookup_ip_route:
- * @multi_idx:
- * @idx_type:
- * @needle:
- * @cmp_type: after lookup, filter the result by comparing with @cmp_type. Only
- * return the result, if it compares equal to @needle according to this @cmp_type.
- * Note that the index uses %NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST type, so passing
- * that compare-type means not to filter any further.
- *
- * Returns: the found entry or %NULL.
- */
-const NMDedupMultiEntry *
-_nm_ip_config_lookup_ip_route(const NMDedupMultiIndex * multi_idx,
- const NMIPConfigDedupMultiIdxType *idx_type,
- const NMPObject * needle,
- NMPlatformIPRouteCmpType cmp_type)
-{
- const NMDedupMultiEntry *entry;
-
- nm_assert(multi_idx);
- nm_assert(idx_type);
- nm_assert(NM_IN_SET(idx_type->obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
- nm_assert(NMP_OBJECT_GET_TYPE(needle) == idx_type->obj_type);
-
- entry = nm_dedup_multi_index_lookup_obj(multi_idx, &idx_type->parent, needle);
- if (!entry)
- return NULL;
-
- if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
- nm_assert((NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP4_ROUTE
- && nm_platform_ip4_route_cmp(NMP_OBJECT_CAST_IP4_ROUTE(entry->obj),
- NMP_OBJECT_CAST_IP4_ROUTE(needle),
- cmp_type)
- == 0)
- || (NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP6_ROUTE
- && nm_platform_ip6_route_cmp(NMP_OBJECT_CAST_IP6_ROUTE(entry->obj),
- NMP_OBJECT_CAST_IP6_ROUTE(needle),
- cmp_type)
- == 0));
- } else {
- if (NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP4_ROUTE) {
- if (nm_platform_ip4_route_cmp(NMP_OBJECT_CAST_IP4_ROUTE(entry->obj),
- NMP_OBJECT_CAST_IP4_ROUTE(needle),
- cmp_type)
- != 0)
- return NULL;
- } else {
- if (nm_platform_ip6_route_cmp(NMP_OBJECT_CAST_IP6_ROUTE(entry->obj),
- NMP_OBJECT_CAST_IP6_ROUTE(needle),
- cmp_type)
- != 0)
- return NULL;
- }
- }
- return entry;
-}
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE(NMIP4Config,
- PROP_MULTI_IDX,
- PROP_IFINDEX,
- PROP_ADDRESS_DATA,
- PROP_ADDRESSES,
- PROP_ROUTE_DATA,
- PROP_ROUTES,
- PROP_GATEWAY,
- PROP_NAMESERVER_DATA,
- PROP_NAMESERVERS,
- PROP_DOMAINS,
- PROP_SEARCHES,
- PROP_DNS_OPTIONS,
- PROP_WINS_SERVER_DATA,
- PROP_WINS_SERVERS,
- PROP_DNS_PRIORITY, );
-
-typedef struct {
- bool metered : 1;
- bool never_default : 1;
- guint32 mtu;
- int ifindex;
- NMIPConfigSource mtu_source;
- int dns_priority;
- NMSettingConnectionMdns mdns;
- NMSettingConnectionLlmnr llmnr;
- GArray * nameservers;
- GPtrArray * domains;
- GPtrArray * searches;
- GPtrArray * dns_options;
- GArray * nis;
- char * nis_domain;
- GArray * wins;
- GVariant * address_data_variant;
- GVariant * addresses_variant;
- GVariant * route_data_variant;
- GVariant * routes_variant;
- NMDedupMultiIndex * multi_idx;
- const NMPObject * best_default_route;
- union {
- NMIPConfigDedupMultiIdxType idx_ip4_addresses_;
- NMDedupMultiIdxType idx_ip4_addresses;
- };
- union {
- NMIPConfigDedupMultiIdxType idx_ip4_routes_;
- NMDedupMultiIdxType idx_ip4_routes;
- };
- NMIPConfigFlags config_flags;
-} NMIP4ConfigPrivate;
-
-struct _NMIP4Config {
- NMIPConfig parent;
- NMIP4ConfigPrivate _priv;
-};
-
-struct _NMIP4ConfigClass {
- NMIPConfigClass parent;
-};
-
-G_DEFINE_TYPE(NMIP4Config, nm_ip4_config, NM_TYPE_IP_CONFIG)
-
-#define NM_IP4_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP4Config, NM_IS_IP4_CONFIG)
-
-/*****************************************************************************/
-
-static void
-_add_address(NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Address *new);
-static void _add_route(NMIP4Config * self,
- const NMPObject *obj_new,
- const NMPlatformIP4Route *new,
- const NMPObject **out_obj_new);
-static const NMDedupMultiEntry *
-_lookup_route(const NMIP4Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type);
-
-/*****************************************************************************/
-
-int
-nm_ip4_config_get_ifindex(const NMIP4Config *self)
-{
- return NM_IP4_CONFIG_GET_PRIVATE(self)->ifindex;
-}
-
-NMDedupMultiIndex *
-nm_ip4_config_get_multi_idx(const NMIP4Config *self)
-{
- return NM_IP4_CONFIG_GET_PRIVATE(self)->multi_idx;
-}
-
-/*****************************************************************************/
-
-const NMDedupMultiHeadEntry *
-nm_ip4_config_lookup_addresses(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return nm_dedup_multi_index_lookup_head(priv->multi_idx, &priv->idx_ip4_addresses, NULL);
-}
-
-void
-nm_ip_config_iter_ip4_address_init(NMDedupMultiIter *ipconf_iter, const NMIP4Config *self)
-{
- nm_assert(NM_IS_IP4_CONFIG(self));
-
- nm_dedup_multi_iter_init(ipconf_iter, nm_ip4_config_lookup_addresses(self));
-}
-
-/*****************************************************************************/
-
-const NMDedupMultiHeadEntry *
-nm_ip4_config_lookup_routes(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return nm_dedup_multi_index_lookup_head(priv->multi_idx, &priv->idx_ip4_routes, NULL);
-}
-
-void
-nm_ip_config_iter_ip4_route_init(NMDedupMultiIter *ipconf_iter, const NMIP4Config *self)
-{
- nm_assert(NM_IS_IP4_CONFIG(self));
-
- nm_dedup_multi_iter_init(ipconf_iter, nm_ip4_config_lookup_routes(self));
-}
-
-/*****************************************************************************/
-
-const NMPObject *
-_nm_ip_config_best_default_route_find_better(const NMPObject *obj_cur, const NMPObject *obj_cmp)
-{
- nm_assert(!obj_cur
- || NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_cur),
- NMP_OBJECT_TYPE_IP4_ROUTE,
- NMP_OBJECT_TYPE_IP6_ROUTE));
- nm_assert(!obj_cmp
- || (!obj_cur
- && NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_cmp),
- NMP_OBJECT_TYPE_IP4_ROUTE,
- NMP_OBJECT_TYPE_IP6_ROUTE))
- || NMP_OBJECT_GET_TYPE(obj_cur) == NMP_OBJECT_GET_TYPE(obj_cmp));
- nm_assert(!obj_cur || nmp_object_ip_route_is_best_defaut_route(obj_cur));
-
- /* assumes that @obj_cur is already the best default route (or NULL). It checks whether
- * @obj_cmp is also a default route and returns the best of both. */
- if (obj_cmp && nmp_object_ip_route_is_best_defaut_route(obj_cmp)) {
- guint32 metric_cur, metric_cmp;
-
- if (!obj_cur)
- return obj_cmp;
-
- metric_cur = NMP_OBJECT_CAST_IP_ROUTE(obj_cur)->metric;
- metric_cmp = NMP_OBJECT_CAST_IP_ROUTE(obj_cmp)->metric;
-
- if (metric_cmp < metric_cur)
- return obj_cmp;
-
- if (metric_cmp == metric_cur) {
- int c;
-
- /* Routes have the same metric. We still want to deterministically
- * prefer one or the other. It's important to consistently choose one
- * or the other, so that the order doesn't matter how routes are added
- * (and merged). */
- c = nmp_object_cmp(obj_cur, obj_cmp);
- if (c != 0)
- return c < 0 ? obj_cur : obj_cmp;
-
- /* as last resort, compare pointers. */
- if (obj_cmp < obj_cur)
- return obj_cmp;
- }
- }
- return obj_cur;
-}
-
-gboolean
-_nm_ip_config_best_default_route_merge(const NMPObject **best_default_route,
- const NMPObject * new_candidate)
-{
- new_candidate =
- _nm_ip_config_best_default_route_find_better(*best_default_route, new_candidate);
- return nmp_object_ref_set(best_default_route, new_candidate);
-}
-
-const NMPObject *
-nm_ip4_config_best_default_route_get(const NMIP4Config *self)
-{
- g_return_val_if_fail(NM_IS_IP4_CONFIG(self), NULL);
-
- return NM_IP4_CONFIG_GET_PRIVATE(self)->best_default_route;
-}
-
-const NMPObject *
-_nm_ip4_config_best_default_route_find(const NMIP4Config *self)
-{
- NMDedupMultiIter ipconf_iter;
- const NMPObject *new_best_default_route = NULL;
-
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, NULL) {
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route,
- ipconf_iter.current->obj);
- }
- return new_best_default_route;
-}
-
-in_addr_t
-nmtst_ip4_config_get_gateway(NMIP4Config *config)
-{
- const NMPObject *rt;
-
- g_assert(NM_IS_IP4_CONFIG(config));
-
- rt = nm_ip4_config_best_default_route_get(config);
- if (!rt)
- return 0;
- return NMP_OBJECT_CAST_IP4_ROUTE(rt)->gateway;
-}
-
-/*****************************************************************************/
-
-static void
-_notify_addresses(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- nm_clear_g_variant(&priv->address_data_variant);
- nm_clear_g_variant(&priv->addresses_variant);
- nm_gobject_notify_together(self, PROP_ADDRESS_DATA, PROP_ADDRESSES);
-}
-
-static void
-_notify_routes(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- nm_assert(priv->best_default_route == _nm_ip4_config_best_default_route_find(self));
- nm_clear_g_variant(&priv->route_data_variant);
- nm_clear_g_variant(&priv->routes_variant);
- nm_gobject_notify_together(self, PROP_ROUTE_DATA, PROP_ROUTES);
-}
-
-/*****************************************************************************/
-
-static int
-sort_captured_addresses(const CList *lst_a, const CList *lst_b, gconstpointer user_data)
-{
- const NMPlatformIP4Address *addr_a =
- NMP_OBJECT_CAST_IP4_ADDRESS(c_list_entry(lst_a, NMDedupMultiEntry, lst_entries)->obj);
- const NMPlatformIP4Address *addr_b =
- NMP_OBJECT_CAST_IP4_ADDRESS(c_list_entry(lst_b, NMDedupMultiEntry, lst_entries)->obj);
-
- nm_assert(addr_a);
- nm_assert(addr_b);
-
- /* Primary addresses first */
- return NM_FLAGS_HAS(addr_a->n_ifa_flags, IFA_F_SECONDARY)
- - NM_FLAGS_HAS(addr_b->n_ifa_flags, IFA_F_SECONDARY);
-}
-
-NMIP4Config *
-nm_ip4_config_clone(const NMIP4Config *self)
-{
- NMIP4Config *copy;
-
- copy = nm_ip4_config_new(nm_ip4_config_get_multi_idx(self), -1);
- nm_ip4_config_replace(copy, self, NULL);
-
- return copy;
-}
-
-NMIP4Config *
-nm_ip4_config_capture(NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex)
-{
- NMIP4Config * self;
- NMIP4ConfigPrivate * priv;
- const NMDedupMultiHeadEntry *head_entry;
- NMDedupMultiIter iter;
- const NMPObject * plobj = NULL;
-
- nm_assert(ifindex > 0);
-
- /* Slaves have no IP configuration */
- if (nm_platform_link_get_master(platform, ifindex) > 0)
- return NULL;
-
- self = nm_ip4_config_new(multi_idx, ifindex);
- priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex);
- if (head_entry) {
- nmp_cache_iter_for_each (&iter, head_entry, &plobj) {
- if (!_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip4_addresses_,
- ifindex,
- plobj,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL))
- nm_assert_not_reached();
- }
- head_entry = nm_ip4_config_lookup_addresses(self);
- nm_assert(head_entry);
- nm_dedup_multi_head_entry_sort(head_entry, sort_captured_addresses, NULL);
- _notify_addresses(self);
- }
-
- head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex);
-
- /* Extract gateway from default route */
- nmp_cache_iter_for_each (&iter, head_entry, &plobj)
- _add_route(self, plobj, NULL, NULL);
-
- return self;
-}
-
-void
-nm_ip4_config_update_routes_metric(NMIP4Config *self, gint64 metric)
-{
- gs_free NMPlatformIP4Route *routes = NULL;
- gboolean need_update = FALSE;
- const NMPlatformIP4Route * r;
- NMDedupMultiIter iter;
- guint num = 0, i = 0;
-
- nm_ip_config_iter_ip4_route_for_each (&iter, self, &r) {
- if (r->metric != metric)
- need_update = TRUE;
- num++;
- }
- if (!need_update)
- return;
-
- routes = g_new(NMPlatformIP4Route, num);
- nm_ip_config_iter_ip4_route_for_each (&iter, self, &r) {
- routes[i] = *r;
- routes[i].metric = metric;
- i++;
- }
-
- g_object_freeze_notify(G_OBJECT(self));
- nm_ip4_config_reset_routes(self);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_route(self, &routes[i], NULL);
- g_object_thaw_notify(G_OBJECT(self));
-}
-
-void
-nm_ip4_config_add_dependent_routes(NMIP4Config *self,
- guint32 route_table,
- guint32 route_metric,
- gboolean is_vrf,
- GPtrArray ** out_ip4_dev_route_blacklist)
-{
- GPtrArray * ip4_dev_route_blacklist = NULL;
- const NMPlatformIP4Address *my_addr;
- const NMPlatformIP4Route * my_route;
- int ifindex;
- NMDedupMultiIter iter;
-
- g_return_if_fail(NM_IS_IP4_CONFIG(self));
-
- ifindex = nm_ip4_config_get_ifindex(self);
- g_return_if_fail(ifindex > 0);
-
- /* For IPv6 slaac, we explicitly add the device-routes (onlink) to NMIP6Config.
- * As we don't do that for IPv4 (and manual IPv6 addresses), add them explicitly. */
-
- nm_ip_config_iter_ip4_address_for_each (&iter, self, &my_addr) {
- nm_auto_nmpobj NMPObject *r = NULL;
- NMPlatformIP4Route * route;
- in_addr_t network;
-
- if (my_addr->plen == 0)
- continue;
-
- nm_assert(my_addr->plen <= 32);
-
- /* The destination network depends on the peer-address. */
- network = nm_utils_ip4_address_clear_host_address(my_addr->peer_address, my_addr->plen);
-
- if (my_addr->external)
- continue;
-
- if (nm_utils_ip4_address_is_zeronet(network)) {
- /* Kernel doesn't add device-routes for destinations that
- * start with 0.x.y.z. Skip them. */
- continue;
- }
-
- if (my_addr->plen == 32 && my_addr->address == my_addr->peer_address) {
- /* Kernel doesn't add device-routes for /32 addresses unless
- * they have a peer. */
- continue;
- }
-
- r = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
- route = NMP_OBJECT_CAST_IP4_ROUTE(r);
-
- route->ifindex = ifindex;
- route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
- route->network = network;
- route->plen = my_addr->plen;
- route->pref_src = my_addr->address;
- route->table_coerced = nm_platform_route_table_coerce(route_table);
- route->metric = route_metric;
- route->scope_inv = nm_platform_route_scope_inv(NM_RT_SCOPE_LINK);
-
- nm_platform_ip_route_normalize(AF_INET, (NMPlatformIPRoute *) route);
-
- if (_lookup_route(self, r, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
- /* we already track this route. Don't add it again. */
- } else
- _add_route(self, r, NULL, NULL);
-
- if (out_ip4_dev_route_blacklist
- && (route_table != RT_TABLE_MAIN
- || route_metric != NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE)) {
- nm_auto_nmpobj NMPObject *r_dev = NULL;
-
- r_dev = nmp_object_clone(r, FALSE);
- route = NMP_OBJECT_CAST_IP4_ROUTE(r_dev);
- route->table_coerced = nm_platform_route_table_coerce(RT_TABLE_MAIN);
- route->metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE;
-
- nm_platform_ip_route_normalize(AF_INET, (NMPlatformIPRoute *) route);
-
- if (_lookup_route(self, r_dev, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
- /* we track such a route explicitly. Don't blacklist it. */
- } else {
- if (!ip4_dev_route_blacklist)
- ip4_dev_route_blacklist =
- g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
-
- g_ptr_array_add(ip4_dev_route_blacklist, g_steal_pointer(&r_dev));
- }
- }
- }
-
-again:
- nm_ip_config_iter_ip4_route_for_each (&iter, self, &my_route) {
- NMPlatformIP4Route rt;
-
- if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT(my_route) || my_route->gateway == 0
- || NM_IS_IP_CONFIG_SOURCE_RTPROT(my_route->rt_source)
- || nm_ip4_config_get_direct_route_for_host(
- self,
- my_route->gateway,
- nm_platform_route_table_uncoerce(my_route->table_coerced, TRUE)))
- continue;
-
- rt = *my_route;
- rt.network = my_route->gateway;
- rt.plen = 32;
- rt.gateway = 0;
- _add_route(self, NULL, &rt, NULL);
- /* adding the route might have invalidated the iteration. Start again. */
- goto again;
- }
-
- NM_SET_OUT(out_ip4_dev_route_blacklist, ip4_dev_route_blacklist);
-}
-
-gboolean
-nm_ip4_config_commit(const NMIP4Config * self,
- NMPlatform * platform,
- NMIPRouteTableSyncMode route_table_sync)
-{
- gs_unref_ptrarray GPtrArray *addresses = NULL;
- gs_unref_ptrarray GPtrArray *routes = NULL;
- gs_unref_ptrarray GPtrArray *routes_prune = NULL;
- int ifindex;
- gboolean success = TRUE;
-
- g_return_val_if_fail(NM_IS_IP4_CONFIG(self), FALSE);
-
- ifindex = nm_ip4_config_get_ifindex(self);
- g_return_val_if_fail(ifindex > 0, FALSE);
-
- addresses =
- nm_dedup_multi_objs_to_ptr_array_head(nm_ip4_config_lookup_addresses(self), NULL, NULL);
-
- routes = nm_dedup_multi_objs_to_ptr_array_head(nm_ip4_config_lookup_routes(self), NULL, NULL);
-
- routes_prune =
- nm_platform_ip_route_get_prune_list(platform, AF_INET, ifindex, route_table_sync);
-
- nm_platform_ip4_address_sync(platform, ifindex, addresses);
-
- if (!nm_platform_ip_route_sync(platform, AF_INET, ifindex, routes, routes_prune, NULL))
- success = FALSE;
-
- return success;
-}
-
-void
-nm_ip4_config_merge_setting(NMIP4Config * self,
- NMSettingIPConfig * setting,
- NMSettingConnectionMdns mdns,
- NMSettingConnectionLlmnr llmnr,
- guint32 route_table,
- guint32 route_metric)
-{
- guint naddresses, nroutes, nnameservers, nsearches;
- int i, priority;
- const char *gateway_str;
- guint32 gateway_bin;
-
- if (!setting)
- return;
-
- g_return_if_fail(NM_IS_SETTING_IP4_CONFIG(setting));
-
- g_object_freeze_notify(G_OBJECT(self));
-
- naddresses = nm_setting_ip_config_get_num_addresses(setting);
- nroutes = nm_setting_ip_config_get_num_routes(setting);
- nnameservers = nm_setting_ip_config_get_num_dns(setting);
- nsearches = nm_setting_ip_config_get_num_dns_searches(setting);
-
- /* Gateway */
- if (!nm_setting_ip_config_get_never_default(setting)
- && (gateway_str = nm_setting_ip_config_get_gateway(setting))
- && inet_pton(AF_INET, gateway_str, &gateway_bin) == 1 && gateway_bin) {
- const NMPlatformIP4Route r = {
- .rt_source = NM_IP_CONFIG_SOURCE_USER,
- .gateway = gateway_bin,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = route_metric,
- };
-
- _add_route(self, NULL, &r, NULL);
- }
-
- /* Addresses */
- for (i = 0; i < naddresses; i++) {
- NMIPAddress * s_addr = nm_setting_ip_config_get_address(setting, i);
- GVariant * label;
- NMPlatformIP4Address address;
-
- memset(&address, 0, sizeof(address));
- nm_ip_address_get_address_binary(s_addr, &address.address);
- address.peer_address = address.address;
- address.plen = nm_ip_address_get_prefix(s_addr);
- nm_assert(address.plen <= 32);
- address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
- address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
- address.addr_source = NM_IP_CONFIG_SOURCE_USER;
-
- label = nm_ip_address_get_attribute(s_addr, NM_IP_ADDRESS_ATTRIBUTE_LABEL);
- if (label)
- g_strlcpy(address.label, g_variant_get_string(label, NULL), sizeof(address.label));
-
- _add_address(self, NULL, &address);
- }
-
- /* Routes */
- for (i = 0; i < nroutes; i++) {
- NMIPRoute * s_route = nm_setting_ip_config_get_route(setting, i);
- NMPlatformIP4Route route;
- gint64 m;
-
- if (nm_ip_route_get_family(s_route) != AF_INET) {
- nm_assert_not_reached();
- continue;
- }
-
- memset(&route, 0, sizeof(route));
- nm_ip_route_get_dest_binary(s_route, &route.network);
-
- route.plen = nm_ip_route_get_prefix(s_route);
- nm_assert(route.plen <= 32);
-
- nm_ip_route_get_next_hop_binary(s_route, &route.gateway);
- m = nm_ip_route_get_metric(s_route);
- if (m < 0)
- route.metric = route_metric;
- else
- route.metric = m;
- route.rt_source = NM_IP_CONFIG_SOURCE_USER;
-
- route.network = nm_utils_ip4_address_clear_host_address(route.network, route.plen);
-
- nm_utils_ip_route_attribute_to_platform(AF_INET,
- s_route,
- NM_PLATFORM_IP_ROUTE_CAST(&route),
- route_table);
- _add_route(self, NULL, &route, NULL);
- }
-
- /* DNS */
- if (nm_setting_ip_config_get_ignore_auto_dns(setting)) {
- nm_ip4_config_reset_nameservers(self);
- nm_ip4_config_reset_domains(self);
- nm_ip4_config_reset_searches(self);
- }
- for (i = 0; i < nnameservers; i++) {
- guint32 ip;
-
- if (inet_pton(AF_INET, nm_setting_ip_config_get_dns(setting, i), &ip) == 1)
- nm_ip4_config_add_nameserver(self, ip);
- }
- for (i = 0; i < nsearches; i++)
- nm_ip4_config_add_search(self, nm_setting_ip_config_get_dns_search(setting, i));
-
- i = 0;
- while ((i = nm_setting_ip_config_next_valid_dns_option(setting, i)) >= 0) {
- nm_ip4_config_add_dns_option(self, nm_setting_ip_config_get_dns_option(setting, i));
- i++;
- }
-
- priority = nm_setting_ip_config_get_dns_priority(setting);
- if (priority)
- nm_ip4_config_set_dns_priority(self, priority);
-
- nm_ip4_config_mdns_set(self, mdns);
- nm_ip4_config_llmnr_set(self, llmnr);
-
- nm_ip4_config_set_never_default(self, nm_setting_ip_config_get_never_default(setting));
-
- g_object_thaw_notify(G_OBJECT(self));
-}
-
-NMSetting *
-nm_ip4_config_create_setting(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate * priv;
- NMSettingIPConfig * s_ip4;
- guint nnameservers, nsearches, noptions;
- const char * method = NULL;
- int i;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP4Address *address;
- const NMPlatformIP4Route * route;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
-
- s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
-
- if (!self) {
- g_object_set(s_ip4,
- NM_SETTING_IP_CONFIG_METHOD,
- NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
- NULL);
- return NM_SETTING(s_ip4);
- }
-
- priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- nnameservers = nm_ip4_config_get_num_nameservers(self);
- nsearches = nm_ip4_config_get_num_searches(self);
- noptions = nm_ip4_config_get_num_dns_options(self);
-
- /* Addresses */
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address) {
- NMIPAddress *s_addr;
-
- /* Detect dynamic address */
- if (address->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
- method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
- continue;
- }
-
- /* Static address found. */
- if (!method)
- method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
-
- s_addr = nm_ip_address_new_binary(AF_INET, &address->address, address->plen, NULL);
- if (*address->label)
- nm_ip_address_set_attribute(s_addr,
- NM_IP_ADDRESS_ATTRIBUTE_LABEL,
- g_variant_new_string(address->label));
-
- nm_setting_ip_config_add_address(s_ip4, s_addr);
- nm_ip_address_unref(s_addr);
- }
-
- /* Gateway */
- if (priv->best_default_route && nm_setting_ip_config_get_num_addresses(s_ip4) > 0) {
- g_object_set(
- s_ip4,
- NM_SETTING_IP_CONFIG_GATEWAY,
- _nm_utils_inet4_ntop(NMP_OBJECT_CAST_IP4_ROUTE(priv->best_default_route)->gateway,
- sbuf),
- NULL);
- }
-
- /* Use 'disabled' if the method wasn't previously set */
- if (!method)
- method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
-
- g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, method, NULL);
-
- /* Routes */
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) {
- NMIPRoute *s_route;
-
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route))
- continue;
-
- /* Ignore routes provided by external sources */
- if (route->rt_source
- != nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER))
- continue;
-
- s_route = nm_ip_route_new_binary(AF_INET,
- &route->network,
- route->plen,
- &route->gateway,
- route->metric,
- NULL);
- nm_setting_ip_config_add_route(s_ip4, s_route);
- nm_ip_route_unref(s_route);
- }
-
- /* DNS */
- for (i = 0; i < nnameservers; i++) {
- guint32 nameserver = nm_ip4_config_get_nameserver(self, i);
-
- nm_setting_ip_config_add_dns(s_ip4, _nm_utils_inet4_ntop(nameserver, sbuf));
- }
- for (i = 0; i < nsearches; i++) {
- const char *search = nm_ip4_config_get_search(self, i);
-
- nm_setting_ip_config_add_dns_search(s_ip4, search);
- }
-
- for (i = 0; i < noptions; i++) {
- const char *option = nm_ip4_config_get_dns_option(self, i);
-
- nm_setting_ip_config_add_dns_option(s_ip4, option);
- }
-
- g_object_set(s_ip4,
- NM_SETTING_IP_CONFIG_DNS_PRIORITY,
- nm_ip4_config_get_dns_priority(self),
- NULL);
-
- return NM_SETTING(s_ip4);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_merge(NMIP4Config * dst,
- const NMIP4Config * src,
- NMIPConfigMergeFlags merge_flags,
- guint32 default_route_metric_penalty)
-{
- NMIP4ConfigPrivate * dst_priv;
- const NMIP4ConfigPrivate * src_priv;
- guint32 i;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP4Address *address = NULL;
-
- g_return_if_fail(src != NULL);
- g_return_if_fail(dst != NULL);
-
- dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
- src_priv = NM_IP4_CONFIG_GET_PRIVATE(src);
-
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* addresses */
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, src, &address) {
- if (NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_EXTERNAL) && !address->external) {
- NMPlatformIP4Address a;
-
- a = *address;
- a.external = TRUE;
- _add_address(dst, NULL, &a);
- } else
- _add_address(dst, NMP_OBJECT_UP_CAST(address), NULL);
- }
-
- /* nameservers */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip4_config_get_num_nameservers(src); i++)
- nm_ip4_config_add_nameserver(dst, nm_ip4_config_get_nameserver(src, i));
- }
-
- /* routes */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
- const NMPlatformIP4Route *r_src;
-
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r_src) {
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r_src)) {
- if (NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES)
- && !NM_FLAGS_HAS(src_priv->config_flags,
- NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES))
- continue;
- if (default_route_metric_penalty) {
- NMPlatformIP4Route r = *r_src;
-
- r.metric =
- nm_utils_ip_route_metric_penalize(r.metric, default_route_metric_penalty);
- _add_route(dst, NULL, &r, NULL);
- continue;
- }
- }
- _add_route(dst, ipconf_iter.current->obj, NULL, NULL);
- }
- }
-
- /* domains */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip4_config_get_num_domains(src); i++)
- nm_ip4_config_add_domain(dst, nm_ip4_config_get_domain(src, i));
- }
-
- /* dns searches */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip4_config_get_num_searches(src); i++)
- nm_ip4_config_add_search(dst, nm_ip4_config_get_search(src, i));
- }
-
- /* dns options */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip4_config_get_num_dns_options(src); i++)
- nm_ip4_config_add_dns_option(dst, nm_ip4_config_get_dns_option(src, i));
- }
-
- /* MTU */
- if (src_priv->mtu_source > dst_priv->mtu_source
- || (src_priv->mtu_source == dst_priv->mtu_source
- && ((!dst_priv->mtu && src_priv->mtu)
- || (dst_priv->mtu && src_priv->mtu < dst_priv->mtu))))
- nm_ip4_config_set_mtu(dst, src_priv->mtu, src_priv->mtu_source);
-
- /* NIS */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip4_config_get_num_nis_servers(src); i++)
- nm_ip4_config_add_nis_server(dst, nm_ip4_config_get_nis_server(src, i));
-
- if (nm_ip4_config_get_nis_domain(src))
- nm_ip4_config_set_nis_domain(dst, nm_ip4_config_get_nis_domain(src));
- }
-
- /* WINS */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip4_config_get_num_wins(src); i++)
- nm_ip4_config_add_wins(dst, nm_ip4_config_get_wins(src, i));
- }
-
- /* metered flag */
- nm_ip4_config_set_metered(dst,
- nm_ip4_config_get_metered(dst) || nm_ip4_config_get_metered(src));
-
- /* never default */
- nm_ip4_config_set_never_default(dst,
- nm_ip4_config_get_never_default(dst)
- || nm_ip4_config_get_never_default(src));
-
- /* DNS priority */
- if (nm_ip4_config_get_dns_priority(src))
- nm_ip4_config_set_dns_priority(dst, nm_ip4_config_get_dns_priority(src));
-
- /* mdns */
- nm_ip4_config_mdns_set(dst, NM_MAX(nm_ip4_config_mdns_get(src), nm_ip4_config_mdns_get(dst)));
- /* LLMNR */
- nm_ip4_config_llmnr_set(dst,
- NM_MAX(nm_ip4_config_llmnr_get(src), nm_ip4_config_llmnr_get(dst)));
-
- g_object_thaw_notify(G_OBJECT(dst));
-}
-
-/*****************************************************************************/
-
-static int
-_nameservers_get_index(const NMIP4Config *self, guint32 ns)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->nameservers->len; i++) {
- guint32 n = g_array_index(priv->nameservers, guint32, i);
-
- if (ns == n)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_domains_get_index(const NMIP4Config *self, const char *domain)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->domains->len; i++) {
- const char *d = g_ptr_array_index(priv->domains, i);
-
- if (g_strcmp0(domain, d) == 0)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_searches_get_index(const NMIP4Config *self, const char *search)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->searches->len; i++) {
- const char *s = g_ptr_array_index(priv->searches, i);
-
- if (g_strcmp0(search, s) == 0)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_dns_options_get_index(const NMIP4Config *self, const char *option)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->dns_options->len; i++) {
- const char *s = g_ptr_array_index(priv->dns_options, i);
-
- if (g_strcmp0(option, s) == 0)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_nis_servers_get_index(const NMIP4Config *self, guint32 nis_server)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->nis->len; i++) {
- guint32 n = g_array_index(priv->nis, guint32, i);
-
- if (n == nis_server)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_wins_get_index(const NMIP4Config *self, guint32 wins_server)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->wins->len; i++) {
- guint32 n = g_array_index(priv->wins, guint32, i);
-
- if (n == wins_server)
- return (int) i;
- }
- return -1;
-}
-
-/*****************************************************************************/
-
-/**
- * nm_ip4_config_subtract:
- * @dst: config from which to remove everything in @src
- * @src: config to remove from @dst
- * @default_route_metric_penalty: pretend that on source we applied
- * a route penalty on the default-route. It means, for default routes
- * we don't remove routes that match exactly, but those with a lower
- * metric (with the penalty removed).
- *
- * Removes everything in @src from @dst.
- */
-void
-nm_ip4_config_subtract(NMIP4Config * dst,
- const NMIP4Config *src,
- guint32 default_route_metric_penalty)
-{
- NMIP4ConfigPrivate * dst_priv;
- guint i;
- int idx;
- const NMPlatformIP4Address *a;
- const NMPlatformIP4Route * r;
- NMDedupMultiIter ipconf_iter;
- gboolean changed;
- gboolean changed_default_route;
-
- g_return_if_fail(src != NULL);
- g_return_if_fail(dst != NULL);
-
- dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
-
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* addresses */
- changed = FALSE;
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, src, &a) {
- if (nm_dedup_multi_index_remove_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip4_addresses,
- NMP_OBJECT_UP_CAST(a),
- NULL))
- changed = TRUE;
- }
- if (changed)
- _notify_addresses(dst);
-
- /* nameservers */
- for (i = 0; i < nm_ip4_config_get_num_nameservers(src); i++) {
- idx = _nameservers_get_index(dst, nm_ip4_config_get_nameserver(src, i));
- if (idx >= 0)
- nm_ip4_config_del_nameserver(dst, idx);
- }
-
- /* routes */
- changed = FALSE;
- changed_default_route = FALSE;
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
- const NMPObject * o_src = NMP_OBJECT_UP_CAST(r);
- NMPObject o_lookup_copy;
- const NMPObject * o_lookup;
- nm_auto_nmpobj const NMPObject *obj_old = NULL;
-
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) && default_route_metric_penalty) {
- NMPlatformIP4Route *rr;
-
- /* the default route was penalized when merging it to the combined ip-config.
- * When subtracting the routes, we must re-do that process when comparing
- * the routes. */
- o_lookup = nmp_object_stackinit_obj(&o_lookup_copy, o_src);
- rr = NMP_OBJECT_CAST_IP4_ROUTE(&o_lookup_copy);
- rr->metric =
- nm_utils_ip_route_metric_penalize(rr->metric, default_route_metric_penalty);
- } else
- o_lookup = o_src;
-
- if (nm_dedup_multi_index_remove_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip4_routes,
- o_lookup,
- (gconstpointer *) &obj_old)) {
- if (dst_priv->best_default_route == obj_old) {
- nm_clear_nmp_object(&dst_priv->best_default_route);
- changed_default_route = TRUE;
- }
- changed = TRUE;
- }
- }
- if (changed_default_route) {
- nmp_object_ref_set(&dst_priv->best_default_route,
- _nm_ip4_config_best_default_route_find(dst));
- _notify(dst, PROP_GATEWAY);
- }
- if (changed)
- _notify_routes(dst);
-
- /* domains */
- for (i = 0; i < nm_ip4_config_get_num_domains(src); i++) {
- idx = _domains_get_index(dst, nm_ip4_config_get_domain(src, i));
- if (idx >= 0)
- nm_ip4_config_del_domain(dst, idx);
- }
-
- /* dns searches */
- for (i = 0; i < nm_ip4_config_get_num_searches(src); i++) {
- idx = _searches_get_index(dst, nm_ip4_config_get_search(src, i));
- if (idx >= 0)
- nm_ip4_config_del_search(dst, idx);
- }
-
- /* dns options */
- for (i = 0; i < nm_ip4_config_get_num_dns_options(src); i++) {
- idx = _dns_options_get_index(dst, nm_ip4_config_get_dns_option(src, i));
- if (idx >= 0)
- nm_ip4_config_del_dns_option(dst, idx);
- }
-
- /* MTU */
- if (nm_ip4_config_get_mtu(src) == nm_ip4_config_get_mtu(dst)
- && nm_ip4_config_get_mtu_source(src) == nm_ip4_config_get_mtu_source(dst))
- nm_ip4_config_set_mtu(dst, 0, NM_IP_CONFIG_SOURCE_UNKNOWN);
-
- /* NIS */
- for (i = 0; i < nm_ip4_config_get_num_nis_servers(src); i++) {
- idx = _nis_servers_get_index(dst, nm_ip4_config_get_nis_server(src, i));
- if (idx >= 0)
- nm_ip4_config_del_nis_server(dst, idx);
- }
-
- if (g_strcmp0(nm_ip4_config_get_nis_domain(src), nm_ip4_config_get_nis_domain(dst)) == 0)
- nm_ip4_config_set_nis_domain(dst, NULL);
-
- /* WINS */
- for (i = 0; i < nm_ip4_config_get_num_wins(src); i++) {
- idx = _wins_get_index(dst, nm_ip4_config_get_wins(src, i));
- if (idx >= 0)
- nm_ip4_config_del_wins(dst, idx);
- }
-
- /* DNS priority */
- if (nm_ip4_config_get_dns_priority(src) == nm_ip4_config_get_dns_priority(dst))
- nm_ip4_config_set_dns_priority(dst, 0);
-
- /* mdns */
- if (nm_ip4_config_mdns_get(src) == nm_ip4_config_mdns_get(dst))
- nm_ip4_config_mdns_set(dst, NM_SETTING_CONNECTION_MDNS_DEFAULT);
-
- /* LLMNR */
- if (nm_ip4_config_llmnr_get(src) == nm_ip4_config_llmnr_get(dst))
- nm_ip4_config_llmnr_set(dst, NM_SETTING_CONNECTION_LLMNR_DEFAULT);
-
- g_object_thaw_notify(G_OBJECT(dst));
-}
-
-static gboolean
-_nm_ip4_config_intersect_helper(NMIP4Config * dst,
- const NMIP4Config *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty,
- gboolean update_dst)
-{
- NMIP4ConfigPrivate * dst_priv;
- const NMIP4ConfigPrivate * src_priv;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP4Address *a;
- const NMPlatformIP4Route * r;
- const NMPObject * new_best_default_route;
- gboolean changed, result = FALSE;
-
- g_return_val_if_fail(src, FALSE);
- g_return_val_if_fail(dst, FALSE);
-
- dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
- src_priv = NM_IP4_CONFIG_GET_PRIVATE(src);
-
- if (update_dst)
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* addresses */
- if (intersect_addresses) {
- changed = FALSE;
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, dst, &a) {
- if (nm_dedup_multi_index_lookup_obj(src_priv->multi_idx,
- &src_priv->idx_ip4_addresses,
- NMP_OBJECT_UP_CAST(a)))
- continue;
-
- if (!update_dst)
- return TRUE;
-
- if (nm_dedup_multi_index_remove_entry(dst_priv->multi_idx, ipconf_iter.current) != 1)
- nm_assert_not_reached();
- changed = TRUE;
- }
- if (changed) {
- _notify_addresses(dst);
- result = TRUE;
- }
- }
-
- /* ignore nameservers */
-
- /* routes */
- if (!intersect_routes)
- goto skip_routes;
-
- changed = FALSE;
- new_best_default_route = NULL;
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
- const NMPObject *o_dst = NMP_OBJECT_UP_CAST(r);
- const NMPObject *o_lookup;
- NMPObject o_lookup_copy;
-
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) && default_route_metric_penalty) {
- NMPlatformIP4Route *rr;
-
- /* the default route was penalized when merging it to the combined ip-config.
- * When intersecting the routes, we must re-do that process when comparing
- * the routes. */
- o_lookup = nmp_object_stackinit_obj(&o_lookup_copy, o_dst);
- rr = NMP_OBJECT_CAST_IP4_ROUTE(&o_lookup_copy);
- rr->metric =
- nm_utils_ip_route_metric_penalize(rr->metric, default_route_metric_penalty);
- } else
- o_lookup = o_dst;
-
- if (nm_dedup_multi_index_lookup_obj(src_priv->multi_idx,
- &src_priv->idx_ip4_routes,
- o_lookup)) {
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route, o_dst);
- continue;
- }
-
- if (!update_dst)
- return TRUE;
-
- if (nm_dedup_multi_index_remove_entry(dst_priv->multi_idx, ipconf_iter.current) != 1)
- nm_assert_not_reached();
- changed = TRUE;
- }
- if (nmp_object_ref_set(&dst_priv->best_default_route, new_best_default_route)) {
- nm_assert(changed);
- _notify(dst, PROP_GATEWAY);
- }
-
- if (changed) {
- _notify_routes(dst);
- result = TRUE;
- }
-
-skip_routes:
- /* ignore domains */
- /* ignore dns searches */
- /* ignore dns options */
- /* ignore NIS */
- /* ignore WINS */
- /* ignore mdns */
- /* ignore LLMNR */
-
- if (update_dst)
- g_object_thaw_notify(G_OBJECT(dst));
- return result;
-}
-
-/**
- * nm_ip4_config_intersect:
- * @dst: a configuration to be updated
- * @src: another configuration
- * @intersect_addresses: whether addresses should be intersected
- * @intersect_routes: whether routes should be intersected
- * @default_route_metric_penalty: the default route metric penalty
- *
- * Computes the intersection between @src and @dst and updates @dst in place
- * with the result.
- */
-void
-nm_ip4_config_intersect(NMIP4Config * dst,
- const NMIP4Config *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty)
-{
- _nm_ip4_config_intersect_helper(dst,
- src,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty,
- TRUE);
-}
-
-/**
- * nm_ip4_config_intersect_alloc:
- * @a: a configuration
- * @b: another configuration
- * @intersect_addresses: whether addresses should be intersected
- * @intersect_routes: whether routes should be intersected
- * @default_route_metric_penalty: the default route metric penalty
- *
- * Computes the intersection between @a and @b and returns the result in a newly
- * allocated configuration. As a special case, if @a and @b are identical (with
- * respect to the only properties considered - addresses and routes) the
- * functions returns NULL so that one of existing configuration can be reused
- * without allocation.
- *
- * Returns: the intersection between @a and @b, or %NULL if the result is equal
- * to @a and @b.
- */
-NMIP4Config *
-nm_ip4_config_intersect_alloc(const NMIP4Config *a,
- const NMIP4Config *b,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty)
-{
- NMIP4Config *a_copy;
-
- if (_nm_ip4_config_intersect_helper((NMIP4Config *) a,
- b,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty,
- FALSE)) {
- a_copy = nm_ip4_config_clone(a);
- _nm_ip4_config_intersect_helper(a_copy,
- b,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty,
- TRUE);
- return a_copy;
- } else
- return NULL;
-}
-
-/**
- * nm_ip4_config_replace:
- * @dst: config to replace with @src content
- * @src: source config to copy
- * @relevant_changes: return whether there are changes to the
- * destination object that are relevant. This is equal to
- * nm_ip4_config_equal() showing any difference.
- *
- * Replaces everything in @dst with @src so that the two configurations
- * contain the same content -- with the exception of the dbus path.
- *
- * Returns: whether the @dst instance changed in any way (including minor changes,
- * that are not signaled by the output parameter @relevant_changes).
- */
-gboolean
-nm_ip4_config_replace(NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes)
-{
-#if NM_MORE_ASSERTS
- gboolean config_equal;
-#endif
- gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal;
- guint i, num;
- NMIP4ConfigPrivate * dst_priv;
- const NMIP4ConfigPrivate * src_priv;
- NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
- const NMDedupMultiHeadEntry *head_entry_src;
- const NMPObject * new_best_default_route;
-
- g_return_val_if_fail(src != NULL, FALSE);
- g_return_val_if_fail(dst != NULL, FALSE);
- g_return_val_if_fail(src != dst, FALSE);
-
-#if NM_MORE_ASSERTS
- config_equal = nm_ip4_config_equal(dst, src);
-#endif
-
- dst_priv = NM_IP4_CONFIG_GET_PRIVATE(dst);
- src_priv = NM_IP4_CONFIG_GET_PRIVATE(src);
-
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* ifindex */
- if (src_priv->ifindex != dst_priv->ifindex) {
- dst_priv->ifindex = src_priv->ifindex;
- has_minor_changes = TRUE;
- }
-
- /* addresses */
- head_entry_src = nm_ip4_config_lookup_addresses(src);
- nm_dedup_multi_iter_init(&ipconf_iter_src, head_entry_src);
- nm_ip_config_iter_ip4_address_init(&ipconf_iter_dst, dst);
- are_equal = TRUE;
- while (TRUE) {
- gboolean has;
- const NMPlatformIP4Address *r_src = NULL;
- const NMPlatformIP4Address *r_dst = NULL;
-
- has = nm_platform_dedup_multi_iter_next_ip4_address(&ipconf_iter_src, &r_src);
- if (has != nm_platform_dedup_multi_iter_next_ip4_address(&ipconf_iter_dst, &r_dst)) {
- are_equal = FALSE;
- has_relevant_changes = TRUE;
- break;
- }
- if (!has)
- break;
-
- if (nm_platform_ip4_address_cmp(r_src, r_dst) != 0) {
- are_equal = FALSE;
- if (r_src->address != r_dst->address || r_src->plen != r_dst->plen
- || r_src->peer_address != r_dst->peer_address) {
- has_relevant_changes = TRUE;
- break;
- }
- }
- }
- if (!are_equal) {
- has_minor_changes = TRUE;
- nm_dedup_multi_index_dirty_set_idx(dst_priv->multi_idx, &dst_priv->idx_ip4_addresses);
- nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
- _nm_ip_config_add_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip4_addresses_,
- dst_priv->ifindex,
- ipconf_iter_src.current->obj,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL);
- }
- nm_dedup_multi_index_dirty_remove_idx(dst_priv->multi_idx,
- &dst_priv->idx_ip4_addresses,
- FALSE);
- _notify_addresses(dst);
- }
-
- /* routes */
- head_entry_src = nm_ip4_config_lookup_routes(src);
- nm_dedup_multi_iter_init(&ipconf_iter_src, head_entry_src);
- nm_ip_config_iter_ip4_route_init(&ipconf_iter_dst, dst);
- are_equal = TRUE;
- while (TRUE) {
- gboolean has;
- const NMPlatformIP4Route *r_src = NULL;
- const NMPlatformIP4Route *r_dst = NULL;
-
- has = nm_platform_dedup_multi_iter_next_ip4_route(&ipconf_iter_src, &r_src);
- if (has != nm_platform_dedup_multi_iter_next_ip4_route(&ipconf_iter_dst, &r_dst)) {
- are_equal = FALSE;
- has_relevant_changes = TRUE;
- break;
- }
- if (!has)
- break;
-
- if (nm_platform_ip4_route_cmp_full(r_src, r_dst) != 0) {
- are_equal = FALSE;
- if (r_src->plen != r_dst->plen
- || !nm_utils_ip4_address_same_prefix(r_src->network, r_dst->network, r_src->plen)
- || r_src->gateway != r_dst->gateway || r_src->metric != r_dst->metric) {
- has_relevant_changes = TRUE;
- break;
- }
- }
- }
- if (!are_equal) {
- has_minor_changes = TRUE;
- new_best_default_route = NULL;
- nm_dedup_multi_index_dirty_set_idx(dst_priv->multi_idx, &dst_priv->idx_ip4_routes);
- nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
- const NMPObject *o = ipconf_iter_src.current->obj;
- const NMPObject *obj_new;
-
- _nm_ip_config_add_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip4_routes_,
- dst_priv->ifindex,
- o,
- NULL,
- FALSE,
- TRUE,
- NULL,
- &obj_new);
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route, obj_new);
- }
- nm_dedup_multi_index_dirty_remove_idx(dst_priv->multi_idx,
- &dst_priv->idx_ip4_routes,
- FALSE);
- if (nmp_object_ref_set(&dst_priv->best_default_route, new_best_default_route))
- _notify(dst, PROP_GATEWAY);
- _notify_routes(dst);
- }
-
- /* nameservers */
- num = nm_ip4_config_get_num_nameservers(src);
- are_equal = num == nm_ip4_config_get_num_nameservers(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (nm_ip4_config_get_nameserver(src, i) != nm_ip4_config_get_nameserver(dst, i)) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip4_config_reset_nameservers(dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_nameserver(dst, nm_ip4_config_get_nameserver(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* domains */
- num = nm_ip4_config_get_num_domains(src);
- are_equal = num == nm_ip4_config_get_num_domains(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (g_strcmp0(nm_ip4_config_get_domain(src, i), nm_ip4_config_get_domain(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip4_config_reset_domains(dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_domain(dst, nm_ip4_config_get_domain(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* dns searches */
- num = nm_ip4_config_get_num_searches(src);
- are_equal = num == nm_ip4_config_get_num_searches(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (g_strcmp0(nm_ip4_config_get_search(src, i), nm_ip4_config_get_search(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip4_config_reset_searches(dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_search(dst, nm_ip4_config_get_search(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* dns options */
- num = nm_ip4_config_get_num_dns_options(src);
- are_equal = num == nm_ip4_config_get_num_dns_options(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (g_strcmp0(nm_ip4_config_get_dns_option(src, i),
- nm_ip4_config_get_dns_option(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip4_config_reset_dns_options(dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_dns_option(dst, nm_ip4_config_get_dns_option(src, i));
- has_relevant_changes = TRUE;
- }
-
- if (src_priv->mdns != dst_priv->mdns) {
- dst_priv->mdns = src_priv->mdns;
- has_relevant_changes = TRUE;
- }
-
- if (src_priv->llmnr != dst_priv->llmnr) {
- dst_priv->llmnr = src_priv->llmnr;
- has_relevant_changes = TRUE;
- }
-
- /* DNS priority */
- if (src_priv->dns_priority != dst_priv->dns_priority) {
- nm_ip4_config_set_dns_priority(dst, src_priv->dns_priority);
- has_minor_changes = TRUE;
- }
-
- /* nis */
- num = nm_ip4_config_get_num_nis_servers(src);
- are_equal = num == nm_ip4_config_get_num_nis_servers(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (nm_ip4_config_get_nis_server(src, i) != nm_ip4_config_get_nis_server(dst, i)) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip4_config_reset_nis_servers(dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_nis_server(dst, nm_ip4_config_get_nis_server(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* nis_domain */
- if (g_strcmp0(src_priv->nis_domain, dst_priv->nis_domain)) {
- nm_ip4_config_set_nis_domain(dst, src_priv->nis_domain);
- has_relevant_changes = TRUE;
- }
-
- /* wins */
- num = nm_ip4_config_get_num_wins(src);
- are_equal = num == nm_ip4_config_get_num_wins(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (nm_ip4_config_get_wins(src, i) != nm_ip4_config_get_wins(dst, i)) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip4_config_reset_wins(dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_wins(dst, nm_ip4_config_get_wins(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* mtu */
- if (src_priv->mtu != dst_priv->mtu || src_priv->mtu_source != dst_priv->mtu_source) {
- nm_ip4_config_set_mtu(dst, src_priv->mtu, src_priv->mtu_source);
- has_minor_changes = TRUE;
- }
-
- /* metered */
- if (src_priv->metered != dst_priv->metered) {
- dst_priv->metered = src_priv->metered;
- has_minor_changes = TRUE;
- }
-
- /* never default */
- if (src_priv->never_default != dst_priv->never_default) {
- dst_priv->never_default = src_priv->never_default;
- has_minor_changes = TRUE;
- }
-
-#if NM_MORE_ASSERTS
- /* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes
- * regardless of config_equal. But config_equal must correspond to has_relevant_changes. */
- nm_assert(config_equal == !has_relevant_changes);
-#endif
-
- g_object_thaw_notify(G_OBJECT(dst));
-
- if (relevant_changes)
- *relevant_changes = has_relevant_changes;
-
- return has_relevant_changes || has_minor_changes;
-}
-
-void
-nm_ip_config_dump(const NMIPConfig *self, const char *detail, NMLogLevel level, NMLogDomain domain)
-{
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP4Address *addr4;
- const NMPlatformIP6Address *addr6;
- const NMPlatformIP4Route * route4;
- const NMPlatformIP6Route * route6;
- const NMIP4Config * ip4;
- const NMIP6Config * ip6;
- int addr_family = AF_UNSPEC;
- char addr_family_char = '?';
- const char * path;
- gconstpointer ptr;
- guint i;
-
- if (self) {
- addr_family = nm_ip_config_get_addr_family(self);
- addr_family_char = nm_utils_addr_family_to_char(addr_family);
- }
-
- nm_log(level, domain, NULL, NULL, "---- NMIP%cConfig %p (%s)", addr_family_char, self, detail);
-
- if (!self)
- return;
-
- path = nm_dbus_object_get_path(NM_DBUS_OBJECT(self));
- if (path)
- nm_log(level, domain, NULL, NULL, " path : %s", path);
-
- if (addr_family == AF_INET) {
- ip4 = NM_IP4_CONFIG(self);
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &addr4) {
- nm_log(level,
- domain,
- NULL,
- NULL,
- " address : %s",
- nm_platform_ip4_address_to_string(addr4, NULL, 0));
- }
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route4) {
- nm_log(level,
- domain,
- NULL,
- NULL,
- " route : %s",
- nm_platform_ip4_route_to_string(route4, NULL, 0));
- }
- } else {
- ip6 = NM_IP6_CONFIG(self);
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &addr6) {
- nm_log(level,
- domain,
- NULL,
- NULL,
- " address : %s",
- nm_platform_ip6_address_to_string(addr6, NULL, 0));
- }
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route6) {
- nm_log(level,
- domain,
- NULL,
- NULL,
- " route : %s",
- nm_platform_ip6_route_to_string(route6, NULL, 0));
- }
- }
-
- for (i = 0; i < nm_ip_config_get_num_nameservers(self); i++) {
- char buf[NM_UTILS_INET_ADDRSTRLEN];
-
- ptr = nm_ip_config_get_nameserver(self, i);
- nm_log(level,
- domain,
- NULL,
- NULL,
- " dns : %s",
- nm_utils_inet_ntop(addr_family, ptr, buf));
- }
-
- for (i = 0; i < nm_ip_config_get_num_domains(self); i++)
- nm_log(level, domain, NULL, NULL, " domain : %s", nm_ip_config_get_domain(self, i));
-
- for (i = 0; i < nm_ip_config_get_num_searches(self); i++)
- nm_log(level, domain, NULL, NULL, " search : %s", nm_ip_config_get_search(self, i));
-
- for (i = 0; i < nm_ip_config_get_num_dns_options(self); i++)
- nm_log(level, domain, NULL, NULL, "dns-option: %s", nm_ip_config_get_dns_option(self, i));
-
- nm_log(level, domain, NULL, NULL, " dns-prio : %d", nm_ip_config_get_dns_priority(self));
-
- if (addr_family == AF_INET) {
- ip4 = NM_IP4_CONFIG(self);
- nm_log(level,
- domain,
- NULL,
- NULL,
- " mtu : %" G_GUINT32_FORMAT " (source: %d)",
- nm_ip4_config_get_mtu(ip4),
- (int) nm_ip4_config_get_mtu_source(ip4));
- nm_log(level, domain, NULL, NULL, " metered : %d", (int) nm_ip4_config_get_metered(ip4));
- }
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_reset_addresses(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_addresses) > 0)
- _notify_addresses(self);
-}
-
-static void
-_add_address(NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Address *new)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip4_addresses_,
- priv->ifindex,
- obj_new,
- (const NMPlatformObject *) new,
- TRUE,
- FALSE,
- NULL,
- NULL))
- _notify_addresses(self);
-}
-
-/**
- * nm_ip4_config_add_address:
- * @self: the #NMIP4Config
- * @new: the new address to add to @self
- *
- * Adds the new address to @self. If an address with the same basic properties
- * (address, prefix) already exists in @self, it is overwritten with the
- * lifetime and preferred of @new. The source is also overwritten by the source
- * from @new if that source is higher priority.
- */
-void
-nm_ip4_config_add_address(NMIP4Config *self, const NMPlatformIP4Address *new)
-{
- g_return_if_fail(self);
- g_return_if_fail(new);
- g_return_if_fail(new->plen <= 32);
- g_return_if_fail(NM_IP4_CONFIG_GET_PRIVATE(self)->ifindex > 0);
-
- _add_address(self, NULL, new);
-}
-
-void
-_nmtst_ip4_config_del_address(NMIP4Config *self, guint i)
-{
- const NMPlatformIP4Address *a;
-
- a = _nmtst_ip4_config_get_address(self, i);
- if (!nm_ip4_config_nmpobj_remove(self, NMP_OBJECT_UP_CAST(a)))
- g_assert_not_reached();
-}
-
-guint
-nm_ip4_config_get_num_addresses(const NMIP4Config *self)
-{
- const NMDedupMultiHeadEntry *head_entry;
-
- head_entry = nm_ip4_config_lookup_addresses(self);
- return head_entry ? head_entry->len : 0;
-}
-
-const NMPlatformIP4Address *
-nm_ip4_config_get_first_address(const NMIP4Config *self)
-{
- NMDedupMultiIter iter;
- const NMPlatformIP4Address *a = NULL;
-
- nm_ip_config_iter_ip4_address_for_each (&iter, self, &a)
- return a;
- return NULL;
-}
-
-const NMPlatformIP4Address *
-_nmtst_ip4_config_get_address(const NMIP4Config *self, guint i)
-{
- NMDedupMultiIter iter = {};
- const NMPlatformIP4Address *a = NULL;
- guint j;
-
- j = 0;
- nm_ip_config_iter_ip4_address_for_each (&iter, self, &a) {
- if (i == j)
- return a;
- j++;
- }
- g_return_val_if_reached(NULL);
-}
-
-gboolean
-nm_ip4_config_address_exists(const NMIP4Config *self, const NMPlatformIP4Address *needle)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- NMPObject obj_stack;
-
- nmp_object_stackinit_id_ip4_address(&obj_stack,
- priv->ifindex,
- needle->address,
- needle->plen,
- needle->peer_address);
- return !!nm_dedup_multi_index_lookup_obj(priv->multi_idx, &priv->idx_ip4_addresses, &obj_stack);
-}
-
-/*****************************************************************************/
-
-static const NMDedupMultiEntry *
-_lookup_route(const NMIP4Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type)
-{
- const NMIP4ConfigPrivate *priv;
-
- nm_assert(NM_IS_IP4_CONFIG(self));
- nm_assert(NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP4_ROUTE);
-
- priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return _nm_ip_config_lookup_ip_route(priv->multi_idx, &priv->idx_ip4_routes_, needle, cmp_type);
-}
-
-void
-nm_ip4_config_reset_routes(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_routes) > 0) {
- if (nm_clear_nmp_object(&priv->best_default_route))
- _notify(self, PROP_GATEWAY);
- _notify_routes(self);
- }
-}
-
-static void
-_add_route(NMIP4Config * self,
- const NMPObject *obj_new,
- const NMPlatformIP4Route *new,
- const NMPObject **out_obj_new)
-{
- NMIP4ConfigPrivate * priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- nm_auto_nmpobj const NMPObject *obj_old = NULL;
- const NMPObject * obj_new_2;
-
- nm_assert((!new) != (!obj_new));
- nm_assert(!new || _route_valid(new));
- nm_assert(!obj_new || _route_valid(NMP_OBJECT_CAST_IP4_ROUTE(obj_new)));
-
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip4_routes_,
- priv->ifindex,
- obj_new,
- (const NMPlatformObject *) new,
- TRUE,
- FALSE,
- &obj_old,
- &obj_new_2)) {
- gboolean changed_default_route = FALSE;
-
- if (priv->best_default_route == obj_old && obj_old != obj_new_2) {
- changed_default_route = TRUE;
- nm_clear_nmp_object(&priv->best_default_route);
- }
- NM_SET_OUT(out_obj_new, nmp_object_ref(obj_new_2));
- if (_nm_ip_config_best_default_route_merge(&priv->best_default_route, obj_new_2))
- changed_default_route = TRUE;
-
- if (changed_default_route)
- _notify(self, PROP_GATEWAY);
- _notify_routes(self);
- } else
- NM_SET_OUT(out_obj_new, nmp_object_ref(obj_new_2));
-}
-
-/**
- * nm_ip4_config_add_route:
- * @self: the #NMIP4Config
- * @new: the new route to add to @self
- * @out_obj_new: (allow-none) (out): the added route object. Must be unrefed
- * by caller.
- *
- * Adds the new route to @self. If a route with the same basic properties
- * (network, prefix) already exists in @self, it is overwritten including the
- * gateway and metric of @new. The source is also overwritten by the source
- * from @new if that source is higher priority.
- */
-void
-nm_ip4_config_add_route(NMIP4Config *self,
- const NMPlatformIP4Route *new,
- const NMPObject **out_obj_new)
-{
- g_return_if_fail(self);
- g_return_if_fail(new);
- g_return_if_fail(new->plen <= 32);
- g_return_if_fail(NM_IP4_CONFIG_GET_PRIVATE(self)->ifindex > 0);
-
- _add_route(self, NULL, new, out_obj_new);
-}
-
-void
-_nmtst_ip4_config_del_route(NMIP4Config *self, guint i)
-{
- const NMPlatformIP4Route *r;
-
- r = _nmtst_ip4_config_get_route(self, i);
- if (!nm_ip4_config_nmpobj_remove(self, NMP_OBJECT_UP_CAST(r)))
- g_assert_not_reached();
-}
-
-guint
-nm_ip4_config_get_num_routes(const NMIP4Config *self)
-{
- const NMDedupMultiHeadEntry *head_entry;
-
- head_entry = nm_ip4_config_lookup_routes(self);
- nm_assert(!head_entry || head_entry->len == c_list_length(&head_entry->lst_entries_head));
- return head_entry ? head_entry->len : 0;
-}
-
-const NMPlatformIP4Route *
-_nmtst_ip4_config_get_route(const NMIP4Config *self, guint i)
-{
- NMDedupMultiIter iter;
- const NMPlatformIP4Route *r = NULL;
- guint j;
-
- j = 0;
- nm_ip_config_iter_ip4_route_for_each (&iter, self, &r) {
- if (i == j)
- return r;
- j++;
- }
- g_return_val_if_reached(NULL);
-}
-
-const NMPlatformIP4Route *
-nm_ip4_config_get_direct_route_for_host(const NMIP4Config *self,
- in_addr_t host,
- guint32 route_table)
-{
- const NMPlatformIP4Route *best_route = NULL;
- const NMPlatformIP4Route *item;
- NMDedupMultiIter ipconf_iter;
-
- g_return_val_if_fail(host, NULL);
-
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &item) {
- if (item->gateway != 0)
- continue;
-
- if (best_route && best_route->plen > item->plen)
- continue;
-
- if (nm_platform_route_table_uncoerce(item->table_coerced, TRUE) != route_table)
- continue;
-
- if (nm_utils_ip4_address_clear_host_address(host, item->plen)
- != nm_utils_ip4_address_clear_host_address(item->network, item->plen))
- continue;
-
- if (best_route && best_route->metric <= item->metric)
- continue;
-
- best_route = item;
- }
- return best_route;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_reset_nameservers(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (priv->nameservers->len != 0) {
- g_array_set_size(priv->nameservers, 0);
- nm_gobject_notify_together(self, PROP_NAMESERVER_DATA, PROP_NAMESERVERS);
- }
-}
-
-void
-nm_ip4_config_add_nameserver(NMIP4Config *self, guint32 new)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- int i;
-
- g_return_if_fail(new != 0);
-
- for (i = 0; i < priv->nameservers->len; i++)
- if (new == g_array_index(priv->nameservers, guint32, i))
- return;
-
- g_array_append_val(priv->nameservers, new);
- nm_gobject_notify_together(self, PROP_NAMESERVER_DATA, PROP_NAMESERVERS);
-}
-
-void
-nm_ip4_config_del_nameserver(NMIP4Config *self, guint i)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->nameservers->len);
-
- g_array_remove_index(priv->nameservers, i);
- nm_gobject_notify_together(self, PROP_NAMESERVER_DATA, PROP_NAMESERVERS);
-}
-
-guint
-nm_ip4_config_get_num_nameservers(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->nameservers->len;
-}
-
-guint32
-nm_ip4_config_get_nameserver(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return g_array_index(priv->nameservers, guint32, i);
-}
-
-const in_addr_t *
-_nm_ip4_config_get_nameserver(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return &g_array_index(priv->nameservers, guint32, i);
-}
-
-/*****************************************************************************/
-
-gboolean
-_nm_ip_config_check_and_add_domain(GPtrArray *array, const char *domain)
-{
- char * copy = NULL;
- size_t len;
-
- g_return_val_if_fail(domain, FALSE);
- g_return_val_if_fail(domain[0] != '\0', FALSE);
-
- if (domain[0] == '.' || strstr(domain, ".."))
- return FALSE;
-
- len = strlen(domain);
- if (domain[len - 1] == '.')
- domain = copy = g_strndup(domain, len - 1);
-
- if (nm_utils_strv_find_first((char **) array->pdata, array->len, domain) >= 0) {
- g_free(copy);
- return FALSE;
- }
-
- g_ptr_array_add(array, copy ?: g_strdup(domain));
- return TRUE;
-}
-
-void
-nm_ip4_config_reset_domains(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (priv->domains->len != 0) {
- g_ptr_array_set_size(priv->domains, 0);
- _notify(self, PROP_DOMAINS);
- }
-}
-
-void
-nm_ip4_config_add_domain(NMIP4Config *self, const char *domain)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (_nm_ip_config_check_and_add_domain(priv->domains, domain))
- _notify(self, PROP_DOMAINS);
-}
-
-void
-nm_ip4_config_del_domain(NMIP4Config *self, guint i)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->domains->len);
-
- g_ptr_array_remove_index(priv->domains, i);
- _notify(self, PROP_DOMAINS);
-}
-
-guint
-nm_ip4_config_get_num_domains(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->domains->len;
-}
-
-const char *
-nm_ip4_config_get_domain(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return g_ptr_array_index(priv->domains, i);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_reset_searches(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (priv->searches->len != 0) {
- g_ptr_array_set_size(priv->searches, 0);
- _notify(self, PROP_SEARCHES);
- }
-}
-
-void
-nm_ip4_config_add_search(NMIP4Config *self, const char *search)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (_nm_ip_config_check_and_add_domain(priv->searches, search))
- _notify(self, PROP_SEARCHES);
-}
-
-void
-nm_ip4_config_del_search(NMIP4Config *self, guint i)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->searches->len);
-
- g_ptr_array_remove_index(priv->searches, i);
- _notify(self, PROP_SEARCHES);
-}
-
-guint
-nm_ip4_config_get_num_searches(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->searches->len;
-}
-
-const char *
-nm_ip4_config_get_search(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return g_ptr_array_index(priv->searches, i);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_reset_dns_options(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (priv->dns_options->len != 0) {
- g_ptr_array_set_size(priv->dns_options, 0);
- _notify(self, PROP_DNS_OPTIONS);
- }
-}
-
-void
-nm_ip4_config_add_dns_option(NMIP4Config *self, const char *new)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- int i;
-
- g_return_if_fail(new != NULL);
- g_return_if_fail(new[0] != '\0');
-
- for (i = 0; i < priv->dns_options->len; i++)
- if (!g_strcmp0(g_ptr_array_index(priv->dns_options, i), new))
- return;
-
- g_ptr_array_add(priv->dns_options, g_strdup(new));
- _notify(self, PROP_DNS_OPTIONS);
-}
-
-void
-nm_ip4_config_del_dns_option(NMIP4Config *self, guint i)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->dns_options->len);
-
- g_ptr_array_remove_index(priv->dns_options, i);
- _notify(self, PROP_DNS_OPTIONS);
-}
-
-guint
-nm_ip4_config_get_num_dns_options(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->dns_options->len;
-}
-
-const char *
-nm_ip4_config_get_dns_option(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return g_ptr_array_index(priv->dns_options, i);
-}
-
-/*****************************************************************************/
-
-NMSettingConnectionMdns
-nm_ip4_config_mdns_get(const NMIP4Config *self)
-{
- return NM_IP4_CONFIG_GET_PRIVATE(self)->mdns;
-}
-
-void
-nm_ip4_config_mdns_set(NMIP4Config *self, NMSettingConnectionMdns mdns)
-{
- NM_IP4_CONFIG_GET_PRIVATE(self)->mdns = mdns;
-}
-
-NMSettingConnectionLlmnr
-nm_ip4_config_llmnr_get(const NMIP4Config *self)
-{
- return NM_IP4_CONFIG_GET_PRIVATE(self)->llmnr;
-}
-
-void
-nm_ip4_config_llmnr_set(NMIP4Config *self, NMSettingConnectionLlmnr llmnr)
-{
- NM_IP4_CONFIG_GET_PRIVATE(self)->llmnr = llmnr;
-}
-
-/*****************************************************************************/
-
-NMIPConfigFlags
-nm_ip4_config_get_config_flags(const NMIP4Config *self)
-{
- return NM_IP4_CONFIG_GET_PRIVATE(self)->config_flags;
-}
-
-void
-nm_ip4_config_set_config_flags(NMIP4Config *self, NMIPConfigFlags flags, NMIPConfigFlags mask)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (mask == 0) {
- /* for convenience, accept 0 mask to set any flags. */
- mask = flags;
- }
-
- nm_assert(!NM_FLAGS_ANY(flags, ~mask));
- priv->config_flags = (flags & mask) | (priv->config_flags & ~mask);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_set_dns_priority(NMIP4Config *self, int priority)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (priority != priv->dns_priority) {
- priv->dns_priority = priority;
- _notify(self, PROP_DNS_PRIORITY);
- }
-}
-
-int
-nm_ip4_config_get_dns_priority(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->dns_priority;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_reset_nis_servers(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_array_set_size(priv->nis, 0);
-}
-
-void
-nm_ip4_config_add_nis_server(NMIP4Config *self, guint32 nis)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- int i;
-
- for (i = 0; i < priv->nis->len; i++)
- if (nis == g_array_index(priv->nis, guint32, i))
- return;
-
- g_array_append_val(priv->nis, nis);
-}
-
-void
-nm_ip4_config_del_nis_server(NMIP4Config *self, guint i)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->nis->len);
-
- g_array_remove_index(priv->nis, i);
-}
-
-guint
-nm_ip4_config_get_num_nis_servers(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->nis->len;
-}
-
-guint32
-nm_ip4_config_get_nis_server(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return g_array_index(priv->nis, guint32, i);
-}
-
-void
-nm_ip4_config_set_nis_domain(NMIP4Config *self, const char *domain)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_free(priv->nis_domain);
- priv->nis_domain = g_strdup(domain);
-}
-
-const char *
-nm_ip4_config_get_nis_domain(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->nis_domain;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_reset_wins(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (priv->wins->len != 0) {
- g_array_set_size(priv->wins, 0);
- nm_gobject_notify_together(self, PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS);
- }
-}
-
-void
-nm_ip4_config_add_wins(NMIP4Config *self, guint32 wins)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- int i;
-
- g_return_if_fail(wins != 0);
-
- for (i = 0; i < priv->wins->len; i++)
- if (wins == g_array_index(priv->wins, guint32, i))
- return;
-
- g_array_append_val(priv->wins, wins);
- nm_gobject_notify_together(self, PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS);
-}
-
-void
-nm_ip4_config_del_wins(NMIP4Config *self, guint i)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->wins->len);
-
- g_array_remove_index(priv->wins, i);
- nm_gobject_notify_together(self, PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS);
-}
-
-guint
-nm_ip4_config_get_num_wins(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->wins->len;
-}
-
-guint32
-nm_ip4_config_get_wins(const NMIP4Config *self, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return g_array_index(priv->wins, guint32, i);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_set_mtu(NMIP4Config *self, guint32 mtu, NMIPConfigSource source)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- if (!mtu)
- source = NM_IP_CONFIG_SOURCE_UNKNOWN;
-
- priv->mtu = mtu;
- priv->mtu_source = source;
-}
-
-guint32
-nm_ip4_config_get_mtu(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->mtu;
-}
-
-NMIPConfigSource
-nm_ip4_config_get_mtu_source(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->mtu_source;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_set_metered(NMIP4Config *self, gboolean metered)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- priv->metered = metered;
-}
-
-gboolean
-nm_ip4_config_get_metered(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->metered;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip4_config_set_never_default(NMIP4Config *self, gboolean never_default)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- priv->never_default = never_default;
-}
-
-gboolean
-nm_ip4_config_get_never_default(const NMIP4Config *self)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- return priv->never_default;
-}
-
-/*****************************************************************************/
-
-const NMPObject *
-nm_ip4_config_nmpobj_lookup(const NMIP4Config *self, const NMPObject *needle)
-{
- const NMIP4ConfigPrivate * priv;
- const NMDedupMultiIdxType *idx_type;
-
- g_return_val_if_fail(NM_IS_IP4_CONFIG(self), NULL);
-
- priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- switch (NMP_OBJECT_GET_TYPE(needle)) {
- case NMP_OBJECT_TYPE_IP4_ADDRESS:
- idx_type = &priv->idx_ip4_addresses;
- break;
- case NMP_OBJECT_TYPE_IP4_ROUTE:
- idx_type = &priv->idx_ip4_routes;
- break;
- default:
- g_return_val_if_reached(NULL);
- }
-
- return nm_dedup_multi_entry_get_obj(
- nm_dedup_multi_index_lookup_obj(priv->multi_idx, idx_type, needle));
-}
-
-gboolean
-nm_ip4_config_nmpobj_remove(NMIP4Config *self, const NMPObject *needle)
-{
- NMIP4ConfigPrivate * priv;
- NMDedupMultiIdxType *idx_type;
- nm_auto_nmpobj const NMPObject *obj_old = NULL;
- guint n;
-
- g_return_val_if_fail(NM_IS_IP4_CONFIG(self), FALSE);
-
- priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- switch (NMP_OBJECT_GET_TYPE(needle)) {
- case NMP_OBJECT_TYPE_IP4_ADDRESS:
- idx_type = &priv->idx_ip4_addresses;
- break;
- case NMP_OBJECT_TYPE_IP4_ROUTE:
- idx_type = &priv->idx_ip4_routes;
- break;
- default:
- g_return_val_if_reached(FALSE);
- }
-
- n = nm_dedup_multi_index_remove_obj(priv->multi_idx,
- idx_type,
- needle,
- (gconstpointer *) &obj_old);
- if (n != 1) {
- nm_assert(n == 0);
- return FALSE;
- }
-
- nm_assert(NMP_OBJECT_GET_TYPE(obj_old) == NMP_OBJECT_GET_TYPE(needle));
-
- switch (NMP_OBJECT_GET_TYPE(obj_old)) {
- case NMP_OBJECT_TYPE_IP4_ADDRESS:
- _notify_addresses(self);
- break;
- case NMP_OBJECT_TYPE_IP4_ROUTE:
- if (priv->best_default_route == obj_old) {
- if (nmp_object_ref_set(&priv->best_default_route,
- _nm_ip4_config_best_default_route_find(self)))
- _notify(self, PROP_GATEWAY);
- }
- _notify_routes(self);
- break;
- default:
- nm_assert_not_reached();
- }
- return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-hash_u32(GChecksum *sum, guint32 n)
-{
- g_checksum_update(sum, (const guint8 *) &n, sizeof(n));
-}
-
-void
-nm_ip4_config_hash(const NMIP4Config *self, GChecksum *sum, gboolean dns_only)
-{
- guint i;
- const char * s;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP4Address *address;
- const NMPlatformIP4Route * route;
- int val;
-
- g_return_if_fail(self);
- g_return_if_fail(sum);
-
- if (!dns_only) {
- nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address) {
- hash_u32(sum, address->address);
- hash_u32(sum, address->plen);
- hash_u32(sum, address->peer_address & _nm_utils_ip4_prefix_to_netmask(address->plen));
- }
-
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) {
- hash_u32(sum, route->network);
- hash_u32(sum, route->plen);
- hash_u32(sum, route->gateway);
- hash_u32(sum, route->metric);
- }
-
- for (i = 0; i < nm_ip4_config_get_num_nis_servers(self); i++)
- hash_u32(sum, nm_ip4_config_get_nis_server(self, i));
-
- s = nm_ip4_config_get_nis_domain(self);
- if (s)
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-
- for (i = 0; i < nm_ip4_config_get_num_nameservers(self); i++)
- hash_u32(sum, nm_ip4_config_get_nameserver(self, i));
-
- for (i = 0; i < nm_ip4_config_get_num_wins(self); i++)
- hash_u32(sum, nm_ip4_config_get_wins(self, i));
-
- for (i = 0; i < nm_ip4_config_get_num_domains(self); i++) {
- s = nm_ip4_config_get_domain(self, i);
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-
- for (i = 0; i < nm_ip4_config_get_num_searches(self); i++) {
- s = nm_ip4_config_get_search(self, i);
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-
- for (i = 0; i < nm_ip4_config_get_num_dns_options(self); i++) {
- s = nm_ip4_config_get_dns_option(self, i);
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-
- val = nm_ip4_config_mdns_get(self);
- if (val != NM_SETTING_CONNECTION_MDNS_DEFAULT)
- g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
-
- val = nm_ip4_config_llmnr_get(self);
- if (val != NM_SETTING_CONNECTION_LLMNR_DEFAULT)
- g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
-
- /* FIXME(ip-config-checksum): the DNS priority should be considered relevant
- * and added into the checksum as well, but this can't be done right now
- * because in the DNS manager we rely on the fact that an empty
- * configuration (i.e. just created) has a zero checksum. This is needed to
- * avoid rewriting resolv.conf when there is no change.
- *
- * The DNS priority initial value depends on the connection type (VPN or
- * not), so it's a bit difficult to add it to checksum maintaining the
- * assumption of checksum(empty)=0
- */
-}
-
-/**
- * nm_ip4_config_equal:
- * @a: first config to compare
- * @b: second config to compare
- *
- * Compares two #NMIP4Configs for basic equality. This means that all
- * attributes must exist in the same order in both configs (addresses, routes,
- * domains, DNS servers, etc) but some attributes (address lifetimes, and address
- * and route sources) are ignored.
- *
- * Returns: %TRUE if the configurations are basically equal to each other,
- * %FALSE if not
- */
-gboolean
-nm_ip4_config_equal(const NMIP4Config *a, const NMIP4Config *b)
-{
- nm_auto_free_checksum GChecksum *a_checksum = g_checksum_new(G_CHECKSUM_SHA1);
- nm_auto_free_checksum GChecksum *b_checksum = g_checksum_new(G_CHECKSUM_SHA1);
- guint8 a_data[NM_UTILS_CHECKSUM_LENGTH_SHA1];
- guint8 b_data[NM_UTILS_CHECKSUM_LENGTH_SHA1];
-
- if (a)
- nm_ip4_config_hash(a, a_checksum, FALSE);
- if (b)
- nm_ip4_config_hash(b, b_checksum, FALSE);
-
- nm_utils_checksum_get_digest(a_checksum, a_data);
- nm_utils_checksum_get_digest(b_checksum, b_data);
- return !memcmp(a_data, b_data, sizeof(a_data));
-}
-
-/*****************************************************************************/
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- NMIP4Config * self = NM_IP4_CONFIG(object);
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
- char addr_str[NM_UTILS_INET_ADDRSTRLEN];
- GVariantBuilder builder_data;
- guint i;
-
- switch (prop_id) {
- case PROP_IFINDEX:
- g_value_set_int(value, priv->ifindex);
- break;
- case PROP_ADDRESS_DATA:
- case PROP_ADDRESSES:
- nm_assert(!!priv->address_data_variant == !!priv->addresses_variant);
-
- if (!priv->address_data_variant) {
- nm_utils_ip_addresses_to_dbus(AF_INET,
- nm_ip4_config_lookup_addresses(self),
- priv->best_default_route,
- NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
- &priv->address_data_variant,
- &priv->addresses_variant);
- g_variant_ref_sink(priv->address_data_variant);
- g_variant_ref_sink(priv->addresses_variant);
- }
-
- g_value_set_variant(value,
- prop_id == PROP_ADDRESS_DATA ? priv->address_data_variant
- : priv->addresses_variant);
- break;
- case PROP_ROUTE_DATA:
- case PROP_ROUTES:
- nm_assert(!!priv->route_data_variant == !!priv->routes_variant);
-
- if (!priv->route_data_variant) {
- nm_utils_ip_routes_to_dbus(AF_INET,
- nm_ip4_config_lookup_routes(self),
- &priv->route_data_variant,
- &priv->routes_variant);
- g_variant_ref_sink(priv->route_data_variant);
- g_variant_ref_sink(priv->routes_variant);
- }
-
- g_value_set_variant(value,
- prop_id == PROP_ROUTE_DATA ? priv->route_data_variant
- : priv->routes_variant);
- break;
- case PROP_GATEWAY:
- if (priv->best_default_route) {
- g_value_take_string(value,
- nm_utils_inet4_ntop_dup(
- NMP_OBJECT_CAST_IP4_ROUTE(priv->best_default_route)->gateway));
- } else
- g_value_set_string(value, NULL);
- break;
- case PROP_NAMESERVER_DATA:
- g_variant_builder_init(&builder_data, G_VARIANT_TYPE("aa{sv}"));
-
- for (i = 0; i < priv->nameservers->len; i++) {
- GVariantBuilder nested_builder;
-
- _nm_utils_inet4_ntop(g_array_index(priv->nameservers, in_addr_t, i), addr_str);
-
- g_variant_builder_init(&nested_builder, G_VARIANT_TYPE("a{sv}"));
- g_variant_builder_add(&nested_builder,
- "{sv}",
- "address",
- g_variant_new_string(addr_str));
- g_variant_builder_add(&builder_data, "a{sv}", &nested_builder);
- }
-
- g_value_take_variant(value, g_variant_builder_end(&builder_data));
- break;
- case PROP_NAMESERVERS:
- g_value_take_variant(
- value,
- nm_g_variant_new_au((const guint32 *) priv->nameservers->data, priv->nameservers->len));
- break;
- case PROP_DOMAINS:
- nm_utils_g_value_set_strv(value, priv->domains);
- break;
- case PROP_SEARCHES:
- nm_utils_g_value_set_strv(value, priv->searches);
- break;
- case PROP_DNS_OPTIONS:
- nm_utils_g_value_set_strv(value, priv->dns_options);
- break;
- case PROP_DNS_PRIORITY:
- g_value_set_int(value, priv->dns_priority);
- break;
- case PROP_WINS_SERVER_DATA:
- g_variant_builder_init(&builder_data, G_VARIANT_TYPE("as"));
- for (i = 0; i < priv->wins->len; i++) {
- g_variant_builder_add(
- &builder_data,
- "s",
- _nm_utils_inet4_ntop(g_array_index(priv->wins, in_addr_t, i), addr_str));
- }
- g_value_take_variant(value, g_variant_builder_end(&builder_data));
- break;
- case PROP_WINS_SERVERS:
- g_value_take_variant(
- value,
- nm_g_variant_new_au((const guint32 *) priv->wins->data, priv->wins->len));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- NMIP4Config * self = NM_IP4_CONFIG(object);
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- switch (prop_id) {
- case PROP_MULTI_IDX:
- /* construct-only */
- priv->multi_idx = g_value_get_pointer(value);
- if (!priv->multi_idx)
- g_return_if_reached();
- nm_dedup_multi_index_ref(priv->multi_idx);
- break;
- case PROP_IFINDEX:
- /* construct-only */
- priv->ifindex = g_value_get_int(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-/*****************************************************************************/
-
-static void
-nm_ip4_config_init(NMIP4Config *self)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_addresses,
- NMP_OBJECT_TYPE_IP4_ADDRESS);
- nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_routes,
- NMP_OBJECT_TYPE_IP4_ROUTE);
-
- priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
- priv->llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
- priv->nameservers = g_array_new(FALSE, FALSE, sizeof(guint32));
- priv->domains = g_ptr_array_new_with_free_func(g_free);
- priv->searches = g_ptr_array_new_with_free_func(g_free);
- priv->dns_options = g_ptr_array_new_with_free_func(g_free);
- priv->nis = g_array_new(FALSE, TRUE, sizeof(guint32));
- priv->wins = g_array_new(FALSE, TRUE, sizeof(guint32));
-}
-
-NMIP4Config *
-nm_ip4_config_new(NMDedupMultiIndex *multi_idx, int ifindex)
-{
- g_return_val_if_fail(ifindex >= -1, NULL);
- return g_object_new(NM_TYPE_IP4_CONFIG,
- NM_IP4_CONFIG_MULTI_IDX,
- multi_idx,
- NM_IP4_CONFIG_IFINDEX,
- ifindex,
- NULL);
-}
-
-static void
-finalize(GObject *object)
-{
- NMIP4Config * self = NM_IP4_CONFIG(object);
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE(self);
-
- nm_clear_nmp_object(&priv->best_default_route);
-
- nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_addresses);
- nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip4_routes);
-
- nm_clear_g_variant(&priv->address_data_variant);
- nm_clear_g_variant(&priv->addresses_variant);
- nm_clear_g_variant(&priv->route_data_variant);
- nm_clear_g_variant(&priv->routes_variant);
-
- g_array_unref(priv->nameservers);
- g_ptr_array_unref(priv->domains);
- g_ptr_array_unref(priv->searches);
- g_ptr_array_unref(priv->dns_options);
- g_array_unref(priv->nis);
- g_free(priv->nis_domain);
- g_array_unref(priv->wins);
-
- G_OBJECT_CLASS(nm_ip4_config_parent_class)->finalize(object);
-
- nm_dedup_multi_index_unref(priv->multi_idx);
-}
-
-static const NMDBusInterfaceInfoExtended interface_info_ip4_config = {
- .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
- NM_DBUS_INTERFACE_IP4_CONFIG,
- .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Addresses",
- "aau",
- NM_IP4_CONFIG_ADDRESSES),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AddressData",
- "aa{sv}",
- NM_IP4_CONFIG_ADDRESS_DATA),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Gateway", "s", NM_IP4_CONFIG_GATEWAY),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Routes", "aau", NM_IP4_CONFIG_ROUTES),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RouteData",
- "aa{sv}",
- NM_IP4_CONFIG_ROUTE_DATA),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NameserverData",
- "aa{sv}",
- NM_IP4_CONFIG_NAMESERVER_DATA),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Nameservers",
- "au",
- NM_IP4_CONFIG_NAMESERVERS),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Domains", "as", NM_IP4_CONFIG_DOMAINS),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Searches",
- "as",
- NM_IP4_CONFIG_SEARCHES),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsOptions",
- "as",
- NM_IP4_CONFIG_DNS_OPTIONS),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsPriority",
- "i",
- NM_IP4_CONFIG_DNS_PRIORITY),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WinsServerData",
- "as",
- NM_IP4_CONFIG_WINS_SERVER_DATA),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WinsServers",
- "au",
- NM_IP4_CONFIG_WINS_SERVERS), ), ),
-};
-
-static void
-nm_ip4_config_class_init(NMIP4ConfigClass *klass)
-{
- GObjectClass * object_class = G_OBJECT_CLASS(klass);
- NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
- NMIPConfigClass * ip_config_class = NM_IP_CONFIG_CLASS(klass);
-
- ip_config_class->is_ipv4 = TRUE;
- ip_config_class->addr_family = AF_INET;
-
- dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/IP4Config");
- dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_ip4_config);
-
- object_class->get_property = get_property;
- object_class->set_property = set_property;
- object_class->finalize = finalize;
-
- obj_properties[PROP_MULTI_IDX] =
- g_param_spec_pointer(NM_IP4_CONFIG_MULTI_IDX,
- "",
- "",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_IFINDEX] =
- g_param_spec_int(NM_IP4_CONFIG_IFINDEX,
- "",
- "",
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ADDRESS_DATA] =
- g_param_spec_variant(NM_IP4_CONFIG_ADDRESS_DATA,
- "",
- "",
- G_VARIANT_TYPE("aa{sv}"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ADDRESSES] =
- g_param_spec_variant(NM_IP4_CONFIG_ADDRESSES,
- "",
- "",
- G_VARIANT_TYPE("aau"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ROUTE_DATA] =
- g_param_spec_variant(NM_IP4_CONFIG_ROUTE_DATA,
- "",
- "",
- G_VARIANT_TYPE("aa{sv}"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ROUTES] = g_param_spec_variant(NM_IP4_CONFIG_ROUTES,
- "",
- "",
- G_VARIANT_TYPE("aau"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_GATEWAY] = g_param_spec_string(NM_IP4_CONFIG_GATEWAY,
- "",
- "",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_NAMESERVER_DATA] =
- g_param_spec_variant(NM_IP4_CONFIG_NAMESERVER_DATA,
- "",
- "",
- G_VARIANT_TYPE("aa{sv}"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_NAMESERVERS] =
- g_param_spec_variant(NM_IP4_CONFIG_NAMESERVERS,
- "",
- "",
- G_VARIANT_TYPE("au"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DOMAINS] = g_param_spec_boxed(NM_IP4_CONFIG_DOMAINS,
- "",
- "",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_SEARCHES] = g_param_spec_boxed(NM_IP4_CONFIG_SEARCHES,
- "",
- "",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DNS_OPTIONS] =
- g_param_spec_boxed(NM_IP4_CONFIG_DNS_OPTIONS,
- "",
- "",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DNS_PRIORITY] = g_param_spec_int(NM_IP4_CONFIG_DNS_PRIORITY,
- "",
- "",
- G_MININT32,
- G_MAXINT32,
- 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WINS_SERVER_DATA] =
- g_param_spec_variant(NM_IP4_CONFIG_WINS_SERVER_DATA,
- "",
- "",
- G_VARIANT_TYPE("as"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WINS_SERVERS] =
- g_param_spec_variant(NM_IP4_CONFIG_WINS_SERVERS,
- "",
- "",
- G_VARIANT_TYPE("au"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-}
diff --git a/src/core/nm-ip4-config.h b/src/core/nm-ip4-config.h
deleted file mode 100644
index 7032a2385e..0000000000
--- a/src/core/nm-ip4-config.h
+++ /dev/null
@@ -1,667 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2008 - 2013 Red Hat, Inc.
- */
-
-#ifndef __NETWORKMANAGER_IP4_CONFIG_H__
-#define __NETWORKMANAGER_IP4_CONFIG_H__
-
-#include "nm-setting-connection.h"
-
-#include "nm-setting-ip4-config.h"
-
-#include "libnm-glib-aux/nm-dedup-multi.h"
-#include "libnm-platform/nmp-object.h"
-#include "nm-ip-config.h"
-
-/*****************************************************************************/
-
-typedef enum _NMIPConfigFlags {
- NM_IP_CONFIG_FLAG_NONE = 0,
-
- /* if set, then the merge flag NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES gets
- * ignored during merge. */
- NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES = (1ull << 0),
-} NMIPConfigFlags;
-
-typedef struct {
- NMDedupMultiIdxType parent;
- NMPObjectType obj_type;
-} NMIPConfigDedupMultiIdxType;
-
-void nm_ip_config_dedup_multi_idx_type_init(NMIPConfigDedupMultiIdxType *idx_type,
- NMPObjectType obj_type);
-
-/*****************************************************************************/
-
-void nm_ip_config_iter_ip4_address_init(NMDedupMultiIter *iter, const NMIP4Config *self);
-void nm_ip_config_iter_ip4_route_init(NMDedupMultiIter *iter, const NMIP4Config *self);
-
-#define nm_ip_config_iter_ip4_address_for_each(iter, self, address) \
- for (nm_ip_config_iter_ip4_address_init((iter), (self)); \
- nm_platform_dedup_multi_iter_next_ip4_address((iter), (address));)
-
-#define nm_ip_config_iter_ip4_route_for_each(iter, self, route) \
- for (nm_ip_config_iter_ip4_route_init((iter), (self)); \
- nm_platform_dedup_multi_iter_next_ip4_route((iter), (route));)
-
-/*****************************************************************************/
-
-const NMPObject *_nm_ip_config_best_default_route_find_better(const NMPObject *obj_cur,
- const NMPObject *obj_cmp);
-gboolean _nm_ip_config_best_default_route_merge(const NMPObject **best_default_route,
- const NMPObject * new_candidate);
-
-/*****************************************************************************/
-
-gboolean _nm_ip_config_add_obj(NMDedupMultiIndex * multi_idx,
- NMIPConfigDedupMultiIdxType *idx_type,
- int ifindex,
- const NMPObject * obj_new,
- const NMPlatformObject * pl_new,
- gboolean merge,
- gboolean append_force,
- const NMPObject ** out_obj_old,
- const NMPObject ** out_obj_new);
-
-const NMDedupMultiEntry *_nm_ip_config_lookup_ip_route(const NMDedupMultiIndex * multi_idx,
- const NMIPConfigDedupMultiIdxType *idx_type,
- const NMPObject * needle,
- NMPlatformIPRouteCmpType cmp_type);
-
-/*****************************************************************************/
-
-#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type())
-#define NM_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IP4_CONFIG, NMIP4Config))
-#define NM_IP4_CONFIG_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass))
-#define NM_IS_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_IP4_CONFIG))
-#define NM_IS_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_IP4_CONFIG))
-#define NM_IP4_CONFIG_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass))
-
-typedef struct _NMIP4ConfigClass NMIP4ConfigClass;
-
-/* internal */
-#define NM_IP4_CONFIG_MULTI_IDX "multi-idx"
-#define NM_IP4_CONFIG_IFINDEX "ifindex"
-
-/* public*/
-#define NM_IP4_CONFIG_ADDRESS_DATA "address-data"
-#define NM_IP4_CONFIG_ROUTE_DATA "route-data"
-#define NM_IP4_CONFIG_GATEWAY "gateway"
-#define NM_IP4_CONFIG_NAMESERVER_DATA "nameserver-data"
-#define NM_IP4_CONFIG_DOMAINS "domains"
-#define NM_IP4_CONFIG_SEARCHES "searches"
-#define NM_IP4_CONFIG_DNS_OPTIONS "dns-options"
-#define NM_IP4_CONFIG_DNS_PRIORITY "dns-priority"
-#define NM_IP4_CONFIG_WINS_SERVER_DATA "wins-server-data"
-
-/* deprecated */
-#define NM_IP4_CONFIG_ADDRESSES "addresses"
-#define NM_IP4_CONFIG_ROUTES "routes"
-#define NM_IP4_CONFIG_NAMESERVERS "nameservers"
-#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers"
-
-GType nm_ip4_config_get_type(void);
-
-NMIP4Config *nm_ip4_config_new(NMDedupMultiIndex *multi_idx, int ifindex);
-
-NMIP4Config *nm_ip4_config_clone(const NMIP4Config *self);
-int nm_ip4_config_get_ifindex(const NMIP4Config *self);
-
-NMDedupMultiIndex *nm_ip4_config_get_multi_idx(const NMIP4Config *self);
-
-NMIP4Config *nm_ip4_config_capture(NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex);
-
-void nm_ip4_config_add_dependent_routes(NMIP4Config *self,
- guint32 route_table,
- guint32 route_metric,
- gboolean is_vrf,
- GPtrArray ** out_ip4_dev_route_blacklist);
-
-gboolean nm_ip4_config_commit(const NMIP4Config * self,
- NMPlatform * platform,
- NMIPRouteTableSyncMode route_table_sync);
-
-void nm_ip4_config_merge_setting(NMIP4Config * self,
- NMSettingIPConfig * setting,
- NMSettingConnectionMdns mdns,
- NMSettingConnectionLlmnr llmnr,
- guint32 route_table,
- guint32 route_metric);
-NMSetting *nm_ip4_config_create_setting(const NMIP4Config *self);
-
-void nm_ip4_config_merge(NMIP4Config * dst,
- const NMIP4Config * src,
- NMIPConfigMergeFlags merge_flags,
- guint32 default_route_metric_penalty);
-void nm_ip4_config_subtract(NMIP4Config * dst,
- const NMIP4Config *src,
- guint32 default_route_metric_penalty);
-void nm_ip4_config_intersect(NMIP4Config * dst,
- const NMIP4Config *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty);
-NMIP4Config *nm_ip4_config_intersect_alloc(const NMIP4Config *a,
- const NMIP4Config *b,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty);
-gboolean
-nm_ip4_config_replace(NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes);
-
-const NMPObject *nm_ip4_config_best_default_route_get(const NMIP4Config *self);
-const NMPObject *_nm_ip4_config_best_default_route_find(const NMIP4Config *self);
-
-in_addr_t nmtst_ip4_config_get_gateway(NMIP4Config *config);
-
-NMSettingConnectionMdns nm_ip4_config_mdns_get(const NMIP4Config *self);
-void nm_ip4_config_mdns_set(NMIP4Config *self, NMSettingConnectionMdns mdns);
-NMSettingConnectionLlmnr nm_ip4_config_llmnr_get(const NMIP4Config *self);
-void nm_ip4_config_llmnr_set(NMIP4Config *self, NMSettingConnectionLlmnr llmnr);
-
-void nm_ip4_config_set_config_flags(NMIP4Config *self, NMIPConfigFlags flags, NMIPConfigFlags mask);
-NMIPConfigFlags nm_ip4_config_get_config_flags(const NMIP4Config *self);
-
-const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses(const NMIP4Config *self);
-void nm_ip4_config_reset_addresses(NMIP4Config *self);
-void nm_ip4_config_add_address(NMIP4Config *self, const NMPlatformIP4Address *address);
-void _nmtst_ip4_config_del_address(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_addresses(const NMIP4Config *self);
-const NMPlatformIP4Address *nm_ip4_config_get_first_address(const NMIP4Config *self);
-const NMPlatformIP4Address *_nmtst_ip4_config_get_address(const NMIP4Config *self, guint i);
-gboolean nm_ip4_config_address_exists(const NMIP4Config *self, const NMPlatformIP4Address *address);
-
-const NMDedupMultiHeadEntry *nm_ip4_config_lookup_routes(const NMIP4Config *self);
-void nm_ip4_config_reset_routes(NMIP4Config *self);
-void nm_ip4_config_add_route(NMIP4Config * self,
- const NMPlatformIP4Route *route,
- const NMPObject ** out_obj_new);
-void _nmtst_ip4_config_del_route(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_routes(const NMIP4Config *self);
-const NMPlatformIP4Route * _nmtst_ip4_config_get_route(const NMIP4Config *self, guint i);
-
-const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host(const NMIP4Config *self,
- in_addr_t host,
- guint32 route_table);
-void nm_ip4_config_update_routes_metric(NMIP4Config *self, gint64 metric);
-
-void nm_ip4_config_reset_nameservers(NMIP4Config *self);
-void nm_ip4_config_add_nameserver(NMIP4Config *self, guint32 nameserver);
-
-static inline void
-_nm_ip4_config_add_nameserver(NMIP4Config *self, const guint32 *nameserver)
-{
- nm_ip4_config_add_nameserver(self, *nameserver);
-}
-
-void nm_ip4_config_del_nameserver(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_nameservers(const NMIP4Config *self);
-guint32 nm_ip4_config_get_nameserver(const NMIP4Config *self, guint i);
-const in_addr_t *_nm_ip4_config_get_nameserver(const NMIP4Config *self, guint i);
-
-void nm_ip4_config_reset_domains(NMIP4Config *self);
-void nm_ip4_config_add_domain(NMIP4Config *self, const char *domain);
-void nm_ip4_config_del_domain(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_domains(const NMIP4Config *self);
-const char *nm_ip4_config_get_domain(const NMIP4Config *self, guint i);
-
-void nm_ip4_config_reset_searches(NMIP4Config *self);
-void nm_ip4_config_add_search(NMIP4Config *self, const char *search);
-void nm_ip4_config_del_search(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_searches(const NMIP4Config *self);
-const char *nm_ip4_config_get_search(const NMIP4Config *self, guint i);
-
-void nm_ip4_config_reset_dns_options(NMIP4Config *self);
-void nm_ip4_config_add_dns_option(NMIP4Config *self, const char *option);
-void nm_ip4_config_del_dns_option(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_dns_options(const NMIP4Config *self);
-const char *nm_ip4_config_get_dns_option(const NMIP4Config *self, guint i);
-
-void nm_ip4_config_set_dns_priority(NMIP4Config *self, int priority);
-int nm_ip4_config_get_dns_priority(const NMIP4Config *self);
-
-void nm_ip4_config_reset_nis_servers(NMIP4Config *self);
-void nm_ip4_config_add_nis_server(NMIP4Config *self, guint32 nis);
-void nm_ip4_config_del_nis_server(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_nis_servers(const NMIP4Config *self);
-guint32 nm_ip4_config_get_nis_server(const NMIP4Config *self, guint i);
-void nm_ip4_config_set_nis_domain(NMIP4Config *self, const char *domain);
-const char *nm_ip4_config_get_nis_domain(const NMIP4Config *self);
-
-void nm_ip4_config_reset_wins(NMIP4Config *self);
-void nm_ip4_config_add_wins(NMIP4Config *self, guint32 wins);
-void nm_ip4_config_del_wins(NMIP4Config *self, guint i);
-guint nm_ip4_config_get_num_wins(const NMIP4Config *self);
-guint32 nm_ip4_config_get_wins(const NMIP4Config *self, guint i);
-
-void nm_ip4_config_set_mtu(NMIP4Config *self, guint32 mtu, NMIPConfigSource source);
-guint32 nm_ip4_config_get_mtu(const NMIP4Config *self);
-NMIPConfigSource nm_ip4_config_get_mtu_source(const NMIP4Config *self);
-
-void nm_ip4_config_set_metered(NMIP4Config *self, gboolean metered);
-gboolean nm_ip4_config_get_metered(const NMIP4Config *self);
-
-void nm_ip4_config_set_never_default(NMIP4Config *self, gboolean never_default);
-gboolean nm_ip4_config_get_never_default(const NMIP4Config *self);
-
-const NMPObject *nm_ip4_config_nmpobj_lookup(const NMIP4Config *self, const NMPObject *needle);
-gboolean nm_ip4_config_nmpobj_remove(NMIP4Config *self, const NMPObject *needle);
-
-void nm_ip4_config_hash(const NMIP4Config *self, GChecksum *sum, gboolean dns_only);
-gboolean nm_ip4_config_equal(const NMIP4Config *a, const NMIP4Config *b);
-
-gboolean _nm_ip_config_check_and_add_domain(GPtrArray *array, const char *domain);
-
-void
-nm_ip_config_dump(const NMIPConfig *self, const char *detail, NMLogLevel level, NMLogDomain domain);
-
-/*****************************************************************************/
-
-#include "nm-ip6-config.h"
-
-static inline gboolean
-NM_IS_IP_CONFIG_ADDR_FAMILY(gconstpointer config, int addr_family)
-{
- if (addr_family == AF_UNSPEC)
- return NM_IS_IP4_CONFIG(config) || NM_IS_IP6_CONFIG(config);
- if (addr_family == AF_INET)
- return NM_IS_IP4_CONFIG(config);
- if (addr_family == AF_INET6)
- return NM_IS_IP6_CONFIG(config);
- g_return_val_if_reached(FALSE);
-}
-
-#if _NM_CC_SUPPORT_GENERIC
- /* _NM_IS_IP_CONFIG() is a bit unusual. If _Generic() is supported,
- * it checks whether @config is either NM_IS_IP4_CONFIG() or NM_IS_IP6_CONFIG(),
- * depending on the pointer type of @config.
- *
- * For example, with _Generic() support, the following assertions would fail:
- * NMIP6Config *ptr = (NMIP6Config *) nm_ip4_config_new(...);
- * g_assert (_NM_IS_IP_CONFIG (ptr, ptr));
- * but the following would pass:
- * NMIP4Config *ptr = nm_ip4_config_new(...);
- * g_assert (_NM_IS_IP_CONFIG (ptr, ptr));
- */
- #define _NM_IS_IP_CONFIG(typeexpr, config) \
- ({ \
- const void *const _config = (config); \
- _Generic ((typeexpr), \
- const void *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- const void * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- void *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- void * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- const NMIPConfig *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- const NMIPConfig * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- NMIPConfig *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- NMIPConfig * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
- const NMIP4Config *const: (NM_IS_IP4_CONFIG (_config)), \
- const NMIP4Config * : (NM_IS_IP4_CONFIG (_config)), \
- NMIP4Config *const: (NM_IS_IP4_CONFIG (_config)), \
- NMIP4Config * : (NM_IS_IP4_CONFIG (_config)), \
- const NMIP6Config *const: (NM_IS_IP6_CONFIG (_config)), \
- const NMIP6Config * : (NM_IS_IP6_CONFIG (_config)), \
- NMIP6Config *const: (NM_IS_IP6_CONFIG (_config)), \
- NMIP6Config * : (NM_IS_IP6_CONFIG (_config))); \
- })
-#else
- #define _NM_IS_IP_CONFIG(typeexpr, config) NM_IS_IP_CONFIG(config)
-#endif
-
-#define NM_IP_CONFIG_CAST(config) \
- ({ \
- const void *const _configx = (config); \
- \
- nm_assert(!_configx || _NM_IS_IP_CONFIG((config), _configx)); \
- NM_CONSTCAST_FULL(NMIPConfig, (config), _configx, NMIP4Config, NMIP6Config); \
- })
-
-static inline gboolean
-nm_ip_config_is_ipv4(const NMIPConfig *config)
-{
- if (NM_IP_CONFIG_GET_CLASS(config)->is_ipv4) {
- nm_assert(NM_IS_IP4_CONFIG(config));
- return TRUE;
- }
- nm_assert(NM_IS_IP6_CONFIG(config));
- return FALSE;
-}
-
-static inline int
-nm_ip_config_get_addr_family(const NMIPConfig *config)
-{
- return nm_ip_config_is_ipv4(config) ? AF_INET : AF_INET6;
-}
-
-#define _NM_IP_CONFIG_DISPATCH(config, v4_func, v6_func, ...) \
- G_STMT_START \
- { \
- gconstpointer _config = (config); \
- \
- if (nm_ip_config_is_ipv4(_config)) { \
- return v4_func((NMIP4Config *) _config, ##__VA_ARGS__); \
- } else { \
- return v6_func((NMIP6Config *) _config, ##__VA_ARGS__); \
- } \
- } \
- G_STMT_END
-
-#define _NM_IP_CONFIG_DISPATCH_VOID(config, v4_func, v6_func, ...) \
- G_STMT_START \
- { \
- gconstpointer _config = (config); \
- \
- if (nm_ip_config_is_ipv4(_config)) { \
- v4_func((NMIP4Config *) _config, ##__VA_ARGS__); \
- } else { \
- v6_func((NMIP6Config *) _config, ##__VA_ARGS__); \
- } \
- } \
- G_STMT_END
-
-static inline int
-nm_ip_config_get_ifindex(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_ifindex, nm_ip6_config_get_ifindex);
-}
-
-static inline void
-nm_ip_config_hash(const NMIPConfig *self, GChecksum *sum, gboolean dns_only)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self, nm_ip4_config_hash, nm_ip6_config_hash, sum, dns_only);
-}
-
-static inline gconstpointer
-nm_ip_config_get_first_address(NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_first_address, nm_ip6_config_get_first_address);
-}
-
-static inline void
-nm_ip_config_iter_ip_address_init(NMDedupMultiIter *iter, const NMIPConfig *self)
-{
- if (nm_ip_config_is_ipv4(self))
- nm_ip_config_iter_ip4_address_init(iter, (const NMIP4Config *) self);
- else
- nm_ip_config_iter_ip6_address_init(iter, (const NMIP6Config *) self);
-}
-
-#define nm_ip_config_iter_ip_address_for_each(iter, self, address) \
- for (nm_ip_config_iter_ip_address_init((iter), (self)); \
- nm_platform_dedup_multi_iter_next_ip_address((iter), (address));)
-
-static inline void
-nm_ip_config_iter_ip_route_init(NMDedupMultiIter *iter, const NMIPConfig *self)
-{
- if (nm_ip_config_is_ipv4(self))
- nm_ip_config_iter_ip4_route_init(iter, (const NMIP4Config *) self);
- else
- nm_ip_config_iter_ip6_route_init(iter, (const NMIP6Config *) self);
-}
-
-#define nm_ip_config_iter_ip_route_for_each(iter, self, route) \
- for (nm_ip_config_iter_ip_route_init((iter), (self)); \
- nm_platform_dedup_multi_iter_next_ip_route((iter), (route));)
-
-static inline void
-nm_ip_config_add_address(NMIPConfig *self, const NMPlatformIPAddress *address)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- nm_ip4_config_add_address,
- nm_ip6_config_add_address,
- (gconstpointer) address);
-}
-
-static inline void
-nm_ip_config_reset_addresses(NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self, nm_ip4_config_reset_addresses, nm_ip6_config_reset_addresses);
-}
-
-static inline void
-nm_ip_config_add_route(NMIPConfig *self,
- const NMPlatformIPRoute *new,
- const NMPObject **out_obj_new)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- nm_ip4_config_add_route,
- nm_ip6_config_add_route,
- (gpointer) new,
- out_obj_new);
-}
-
-static inline void
-nm_ip_config_reset_routes(NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self, nm_ip4_config_reset_routes, nm_ip6_config_reset_routes);
-}
-
-static inline int
-nm_ip_config_get_dns_priority(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_dns_priority, nm_ip6_config_get_dns_priority);
-}
-
-static inline void
-nm_ip_config_set_dns_priority(NMIPConfig *self, int priority)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- nm_ip4_config_set_dns_priority,
- nm_ip6_config_set_dns_priority,
- priority);
-}
-
-static inline void
-nm_ip_config_add_nameserver(NMIPConfig *self, const NMIPAddr *ns)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- _nm_ip4_config_add_nameserver,
- nm_ip6_config_add_nameserver,
- (gconstpointer) ns);
-}
-
-static inline void
-nm_ip_config_reset_nameservers(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- nm_ip4_config_reset_nameservers,
- nm_ip6_config_reset_nameservers);
-}
-
-static inline guint
-nm_ip_config_get_num_nameservers(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self,
- nm_ip4_config_get_num_nameservers,
- nm_ip6_config_get_num_nameservers);
-}
-
-static inline gconstpointer
-nm_ip_config_get_nameserver(const NMIPConfig *self, guint i)
-{
- _NM_IP_CONFIG_DISPATCH(self, _nm_ip4_config_get_nameserver, nm_ip6_config_get_nameserver, i);
-}
-
-static inline guint
-nm_ip_config_get_num_domains(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_num_domains, nm_ip6_config_get_num_domains);
-}
-
-static inline const char *
-nm_ip_config_get_domain(const NMIPConfig *self, guint i)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_domain, nm_ip6_config_get_domain, i);
-}
-
-static inline void
-nm_ip_config_reset_searches(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self, nm_ip4_config_reset_searches, nm_ip6_config_reset_searches);
-}
-
-static inline void
-nm_ip_config_add_search(const NMIPConfig *self, const char *new)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self, nm_ip4_config_add_search, nm_ip6_config_add_search, new);
-}
-
-static inline guint
-nm_ip_config_get_num_searches(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_num_searches, nm_ip6_config_get_num_searches);
-}
-
-static inline const char *
-nm_ip_config_get_search(const NMIPConfig *self, guint i)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_search, nm_ip6_config_get_search, i);
-}
-
-static inline guint
-nm_ip_config_get_num_dns_options(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self,
- nm_ip4_config_get_num_dns_options,
- nm_ip6_config_get_num_dns_options);
-}
-
-static inline const char *
-nm_ip_config_get_dns_option(const NMIPConfig *self, guint i)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_dns_option, nm_ip6_config_get_dns_option, i);
-}
-
-static inline const NMPObject *
-nm_ip_config_best_default_route_get(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self,
- nm_ip4_config_best_default_route_get,
- nm_ip6_config_best_default_route_get);
-}
-
-static inline NMIPConfigFlags
-nm_ip_config_get_config_flags(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_config_flags, nm_ip6_config_get_config_flags);
-}
-
-static inline void
-nm_ip_config_set_config_flags(NMIPConfig *self, NMIPConfigFlags flags, NMIPConfigFlags mask)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- nm_ip4_config_set_config_flags,
- nm_ip6_config_set_config_flags,
- flags,
- mask);
-}
-
-static inline gboolean
-nm_ip_config_get_never_default(const NMIPConfig *self)
-{
- _NM_IP_CONFIG_DISPATCH(self, nm_ip4_config_get_never_default, nm_ip6_config_get_never_default);
-}
-
-static inline void
-nm_ip_config_set_never_default(NMIPConfig *self, gboolean never_default)
-{
- _NM_IP_CONFIG_DISPATCH_VOID(self,
- nm_ip4_config_set_never_default,
- nm_ip6_config_set_never_default,
- never_default);
-}
-
-#define _NM_IP_CONFIG_DISPATCH_SET_OP(_return, dst, src, v4_func, v6_func, ...) \
- G_STMT_START \
- { \
- gpointer _dst = (dst); \
- gconstpointer _src = (src); \
- \
- if (nm_ip_config_is_ipv4(_dst)) { \
- _return v4_func((NMIP4Config *) _dst, (const NMIP4Config *) _src, ##__VA_ARGS__); \
- } else { \
- _return v6_func((NMIP6Config *) _dst, (const NMIP6Config *) _src, ##__VA_ARGS__); \
- } \
- } \
- G_STMT_END
-
-static inline void
-nm_ip_config_intersect(NMIPConfig * dst,
- const NMIPConfig *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty)
-{
- _NM_IP_CONFIG_DISPATCH_SET_OP(,
- dst,
- src,
- nm_ip4_config_intersect,
- nm_ip6_config_intersect,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty);
-}
-
-static inline void
-nm_ip_config_subtract(NMIPConfig *dst, const NMIPConfig *src, guint32 default_route_metric_penalty)
-{
- _NM_IP_CONFIG_DISPATCH_SET_OP(,
- dst,
- src,
- nm_ip4_config_subtract,
- nm_ip6_config_subtract,
- default_route_metric_penalty);
-}
-
-static inline void
-nm_ip_config_merge(NMIPConfig * dst,
- const NMIPConfig * src,
- NMIPConfigMergeFlags merge_flags,
- guint32 default_route_metric_penalty)
-{
- _NM_IP_CONFIG_DISPATCH_SET_OP(,
- dst,
- src,
- nm_ip4_config_merge,
- nm_ip6_config_merge,
- merge_flags,
- default_route_metric_penalty);
-}
-
-static inline gboolean
-nm_ip_config_replace(NMIPConfig *dst, const NMIPConfig *src, gboolean *relevant_changes)
-{
- _NM_IP_CONFIG_DISPATCH_SET_OP(
- return, dst, src, nm_ip4_config_replace, nm_ip6_config_replace, relevant_changes);
-}
-
-static inline NMIPConfig *
-nm_ip_config_intersect_alloc(const NMIPConfig *a,
- const NMIPConfig *b,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty)
-{
- if (nm_ip_config_is_ipv4(a)) {
- nm_assert(NM_IS_IP4_CONFIG(a));
- nm_assert(NM_IS_IP4_CONFIG(b));
- return (NMIPConfig *) nm_ip4_config_intersect_alloc((const NMIP4Config *) a,
- (const NMIP4Config *) b,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty);
- } else {
- nm_assert(NM_IS_IP6_CONFIG(a));
- nm_assert(NM_IS_IP6_CONFIG(b));
- return (NMIPConfig *) nm_ip6_config_intersect_alloc((const NMIP6Config *) a,
- (const NMIP6Config *) b,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty);
- }
-}
-
-#endif /* __NETWORKMANAGER_IP4_CONFIG_H__ */
diff --git a/src/core/nm-ip6-config.c b/src/core/nm-ip6-config.c
deleted file mode 100644
index 8793c1c27a..0000000000
--- a/src/core/nm-ip6-config.c
+++ /dev/null
@@ -1,2711 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2005 - 2017 Red Hat, Inc.
- * Copyright (C) 2006 - 2008 Novell, Inc.
- */
-
-#include "src/core/nm-default-daemon.h"
-
-#include "nm-ip6-config.h"
-
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <linux/rtnetlink.h>
-#include <linux/if.h>
-
-#include "libnm-glib-aux/nm-dedup-multi.h"
-
-#include "nm-utils.h"
-#include "libnm-platform/nmp-object.h"
-#include "libnm-platform/nm-platform.h"
-#include "libnm-platform/nm-platform-utils.h"
-#include "libnm-core-intern/nm-core-internal.h"
-#include "NetworkManagerUtils.h"
-#include "nm-ip4-config.h"
-#include "ndisc/nm-ndisc.h"
-#include "nm-dbus-object.h"
-
-/*****************************************************************************/
-
-static gboolean
-_route_valid(const NMPlatformIP6Route *r)
-{
- struct in6_addr n;
-
- return r && r->plen <= 128
- && (memcmp(&r->network,
- nm_utils_ip6_address_clear_host_address(&n, &r->network, r->plen),
- sizeof(n))
- == 0);
-}
-
-/*****************************************************************************/
-
-typedef struct {
- int ifindex;
- int dns_priority;
- NMSettingIP6ConfigPrivacy privacy;
- GArray * nameservers;
- GPtrArray * domains;
- GPtrArray * searches;
- GPtrArray * dns_options;
- GVariant * address_data_variant;
- GVariant * addresses_variant;
- GVariant * route_data_variant;
- GVariant * routes_variant;
- NMDedupMultiIndex * multi_idx;
- const NMPObject * best_default_route;
- union {
- NMIPConfigDedupMultiIdxType idx_ip6_addresses_;
- NMDedupMultiIdxType idx_ip6_addresses;
- };
- union {
- NMIPConfigDedupMultiIdxType idx_ip6_routes_;
- NMDedupMultiIdxType idx_ip6_routes;
- };
- NMIPConfigFlags config_flags;
- bool never_default : 1;
-} NMIP6ConfigPrivate;
-
-struct _NMIP6Config {
- NMIPConfig parent;
- NMIP6ConfigPrivate _priv;
-};
-
-struct _NMIP6ConfigClass {
- NMIPConfigClass parent;
-};
-
-G_DEFINE_TYPE(NMIP6Config, nm_ip6_config, NM_TYPE_IP_CONFIG)
-
-#define NM_IP6_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP6Config, NM_IS_IP6_CONFIG)
-
-NM_GOBJECT_PROPERTIES_DEFINE(NMIP6Config,
- PROP_MULTI_IDX,
- PROP_IFINDEX,
- PROP_ADDRESS_DATA,
- PROP_ADDRESSES,
- PROP_ROUTE_DATA,
- PROP_ROUTES,
- PROP_GATEWAY,
- PROP_NAMESERVERS,
- PROP_DOMAINS,
- PROP_SEARCHES,
- PROP_DNS_OPTIONS,
- PROP_DNS_PRIORITY, );
-
-/*****************************************************************************/
-
-static void
-_add_address(NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Address *new);
-static void _add_route(NMIP6Config * self,
- const NMPObject *obj_new,
- const NMPlatformIP6Route *new,
- const NMPObject **out_obj_new);
-static const NMDedupMultiEntry *
-_lookup_route(const NMIP6Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type);
-
-/*****************************************************************************/
-
-int
-nm_ip6_config_get_ifindex(const NMIP6Config *self)
-{
- return NM_IP6_CONFIG_GET_PRIVATE(self)->ifindex;
-}
-
-NMDedupMultiIndex *
-nm_ip6_config_get_multi_idx(const NMIP6Config *self)
-{
- return NM_IP6_CONFIG_GET_PRIVATE(self)->multi_idx;
-}
-
-void
-nm_ip6_config_set_privacy(NMIP6Config *self, NMSettingIP6ConfigPrivacy privacy)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- priv->privacy = privacy;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_set_never_default(NMIP6Config *self, gboolean never_default)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- priv->never_default = never_default;
-}
-
-gboolean
-nm_ip6_config_get_never_default(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return priv->never_default;
-}
-
-/*****************************************************************************/
-
-const NMDedupMultiHeadEntry *
-nm_ip6_config_lookup_addresses(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return nm_dedup_multi_index_lookup_head(priv->multi_idx, &priv->idx_ip6_addresses, NULL);
-}
-
-void
-nm_ip_config_iter_ip6_address_init(NMDedupMultiIter *ipconf_iter, const NMIP6Config *self)
-{
- nm_assert(NM_IS_IP6_CONFIG(self));
-
- nm_dedup_multi_iter_init(ipconf_iter, nm_ip6_config_lookup_addresses(self));
-}
-
-/*****************************************************************************/
-
-const NMDedupMultiHeadEntry *
-nm_ip6_config_lookup_routes(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return nm_dedup_multi_index_lookup_head(priv->multi_idx, &priv->idx_ip6_routes, NULL);
-}
-
-void
-nm_ip_config_iter_ip6_route_init(NMDedupMultiIter *ipconf_iter, const NMIP6Config *self)
-{
- nm_assert(NM_IS_IP6_CONFIG(self));
-
- nm_dedup_multi_iter_init(ipconf_iter, nm_ip6_config_lookup_routes(self));
-}
-
-/*****************************************************************************/
-
-const NMPObject *
-nm_ip6_config_best_default_route_get(const NMIP6Config *self)
-{
- g_return_val_if_fail(NM_IS_IP6_CONFIG(self), NULL);
-
- return NM_IP6_CONFIG_GET_PRIVATE(self)->best_default_route;
-}
-
-const NMPObject *
-_nm_ip6_config_best_default_route_find(const NMIP6Config *self)
-{
- NMDedupMultiIter ipconf_iter;
- const NMPObject *new_best_default_route = NULL;
-
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, NULL) {
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route,
- ipconf_iter.current->obj);
- }
- return new_best_default_route;
-}
-
-/*****************************************************************************/
-
-static void
-_notify_addresses(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- nm_clear_g_variant(&priv->address_data_variant);
- nm_clear_g_variant(&priv->addresses_variant);
- nm_gobject_notify_together(self, PROP_ADDRESS_DATA, PROP_ADDRESSES);
-}
-
-static void
-_notify_routes(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- nm_assert(priv->best_default_route == _nm_ip6_config_best_default_route_find(self));
- nm_clear_g_variant(&priv->route_data_variant);
- nm_clear_g_variant(&priv->routes_variant);
- nm_gobject_notify_together(self, PROP_ROUTE_DATA, PROP_ROUTES);
-}
-
-/*****************************************************************************/
-
-static int
-sort_captured_addresses(const CList *lst_a, const CList *lst_b, gconstpointer user_data)
-{
- return nm_platform_ip6_address_pretty_sort_cmp(
- NMP_OBJECT_CAST_IP6_ADDRESS(c_list_entry(lst_a, NMDedupMultiEntry, lst_entries)->obj),
- NMP_OBJECT_CAST_IP6_ADDRESS(c_list_entry(lst_b, NMDedupMultiEntry, lst_entries)->obj),
- (((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT(user_data))
- == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR));
-}
-
-gboolean
-_nmtst_ip6_config_addresses_sort(NMIP6Config *self)
-{
- NMIP6ConfigPrivate * priv;
- const NMDedupMultiHeadEntry *head_entry;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(self), FALSE);
-
- head_entry = nm_ip6_config_lookup_addresses(self);
- if (head_entry && head_entry->len > 1) {
- gboolean changed;
- gs_free gconstpointer *addresses_old = NULL;
- guint naddr, j;
- NMDedupMultiIter iter;
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- addresses_old = nm_dedup_multi_objs_to_array_head(head_entry, NULL, NULL, &naddr);
- nm_assert(addresses_old);
- nm_assert(naddr > 0 && naddr == head_entry->len);
-
- nm_dedup_multi_head_entry_sort(head_entry,
- sort_captured_addresses,
- GINT_TO_POINTER(priv->privacy));
-
- changed = FALSE;
- j = 0;
- nm_dedup_multi_iter_for_each (&iter, head_entry) {
- nm_assert(j < naddr);
- if (iter.current->obj != addresses_old[j++])
- changed = TRUE;
- }
- nm_assert(j == naddr);
-
- if (changed) {
- _notify_addresses(self);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-NMIP6Config *
-nm_ip6_config_clone(const NMIP6Config *self)
-{
- NMIP6Config *copy;
-
- copy = nm_ip6_config_new(nm_ip6_config_get_multi_idx(self), -1);
- nm_ip6_config_replace(copy, self, NULL);
-
- return copy;
-}
-
-NMIP6Config *
-nm_ip6_config_capture(NMDedupMultiIndex * multi_idx,
- NMPlatform * platform,
- int ifindex,
- NMSettingIP6ConfigPrivacy use_temporary)
-{
- NMIP6Config * self;
- NMIP6ConfigPrivate * priv;
- const NMDedupMultiHeadEntry *head_entry;
- NMDedupMultiIter iter;
- const NMPObject * plobj = NULL;
-
- nm_assert(ifindex > 0);
-
- /* Slaves have no IP configuration */
- if (nm_platform_link_get_master(platform, ifindex) > 0)
- return NULL;
-
- self = nm_ip6_config_new(multi_idx, ifindex);
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex);
- if (head_entry) {
- nmp_cache_iter_for_each (&iter, head_entry, &plobj) {
- if (!_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip6_addresses_,
- ifindex,
- plobj,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL))
- nm_assert_not_reached();
- }
- head_entry = nm_ip6_config_lookup_addresses(self);
- nm_assert(head_entry);
- nm_dedup_multi_head_entry_sort(head_entry,
- sort_captured_addresses,
- GINT_TO_POINTER(use_temporary));
- _notify_addresses(self);
- }
-
- head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex);
-
- nmp_cache_iter_for_each (&iter, head_entry, &plobj)
- _add_route(self, plobj, NULL, NULL);
-
- return self;
-}
-
-void
-nm_ip6_config_update_routes_metric(NMIP6Config *self, gint64 metric)
-{
- gs_free NMPlatformIP6Route *routes = NULL;
- gboolean need_update = FALSE;
- const NMPlatformIP6Route * r;
- NMDedupMultiIter iter;
- guint num = 0, i = 0;
-
- nm_ip_config_iter_ip6_route_for_each (&iter, self, &r) {
- if (r->metric != metric)
- need_update = TRUE;
- num++;
- }
- if (!need_update)
- return;
-
- routes = g_new(NMPlatformIP6Route, num);
- nm_ip_config_iter_ip6_route_for_each (&iter, self, &r) {
- routes[i] = *r;
- routes[i].metric = metric;
- i++;
- }
-
- g_object_freeze_notify(G_OBJECT(self));
- nm_ip6_config_reset_routes(self);
- for (i = 0; i < num; i++)
- nm_ip6_config_add_route(self, &routes[i], NULL);
- g_object_thaw_notify(G_OBJECT(self));
-}
-
-void
-nm_ip6_config_add_dependent_routes(NMIP6Config *self,
- guint32 route_table,
- guint32 route_metric,
- gboolean is_vrf)
-{
- const NMPlatformIP6Address *my_addr;
- const NMPlatformIP6Route * my_route;
- int ifindex;
- NMDedupMultiIter iter;
-
- g_return_if_fail(NM_IS_IP6_CONFIG(self));
-
- ifindex = nm_ip6_config_get_ifindex(self);
- g_return_if_fail(ifindex > 0);
-
- /* For IPv6 addresses received via SLAAC/autoconf, we explicitly add the
- * device-routes (onlink) to NMIP6Config.
- *
- * For manually added IPv6 routes, add the device routes explicitly. */
-
- nm_ip_config_iter_ip6_address_for_each (&iter, self, &my_addr) {
- NMPlatformIP6Route *route;
- gboolean has_peer;
- int routes_n, routes_i;
-
- if (my_addr->external)
- continue;
-
- if (NM_FLAGS_HAS(my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
- continue;
- if (my_addr->plen == 0)
- continue;
-
- has_peer = !IN6_IS_ADDR_UNSPECIFIED(&my_addr->peer_address);
-
- /* If we have an IPv6 peer, we add two /128 routes
- * (unless, both addresses are identical). */
- routes_n =
- (has_peer && !IN6_ARE_ADDR_EQUAL(&my_addr->address, &my_addr->peer_address)) ? 2 : 1;
-
- for (routes_i = 0; routes_i < routes_n; routes_i++) {
- nm_auto_nmpobj NMPObject *r = NULL;
-
- r = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
- route = NMP_OBJECT_CAST_IP6_ROUTE(r);
-
- route->ifindex = ifindex;
- route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
- route->table_coerced = nm_platform_route_table_coerce(route_table);
- route->metric = route_metric;
-
- if (has_peer) {
- if (routes_i == 0)
- route->network = my_addr->address;
- else
- route->network = my_addr->peer_address;
- route->plen = 128;
- } else {
- nm_utils_ip6_address_clear_host_address(&route->network,
- &my_addr->address,
- my_addr->plen);
- route->plen = my_addr->plen;
- }
-
- nm_platform_ip_route_normalize(AF_INET6, (NMPlatformIPRoute *) route);
-
- if (_lookup_route(self, r, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
- /* we already track this route. Don't add it again. */
- } else
- _add_route(self, r, NULL, NULL);
- }
- }
-
-again:
- nm_ip_config_iter_ip6_route_for_each (&iter, self, &my_route) {
- NMPlatformIP6Route rt;
-
- if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT(my_route)
- || IN6_IS_ADDR_UNSPECIFIED(&my_route->gateway)
- || NM_IS_IP_CONFIG_SOURCE_RTPROT(my_route->rt_source)
- || nm_ip6_config_get_direct_route_for_host(
- self,
- &my_route->gateway,
- nm_platform_route_table_uncoerce(my_route->table_coerced, TRUE)))
- continue;
-
- rt = *my_route;
- rt.network = my_route->gateway;
- rt.plen = 128;
- rt.gateway = in6addr_any;
- _add_route(self, NULL, &rt, NULL);
- /* adding the route might have invalidated the iteration. Start again. */
- goto again;
- }
-}
-
-gboolean
-nm_ip6_config_commit(const NMIP6Config * self,
- NMPlatform * platform,
- NMIPRouteTableSyncMode route_table_sync,
- GPtrArray ** out_temporary_not_available)
-{
- gs_unref_ptrarray GPtrArray *addresses = NULL;
- gs_unref_ptrarray GPtrArray *routes = NULL;
- gs_unref_ptrarray GPtrArray *routes_prune = NULL;
- int ifindex;
- gboolean success = TRUE;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(self), FALSE);
-
- ifindex = nm_ip6_config_get_ifindex(self);
- g_return_val_if_fail(ifindex > 0, FALSE);
-
- addresses =
- nm_dedup_multi_objs_to_ptr_array_head(nm_ip6_config_lookup_addresses(self), NULL, NULL);
-
- routes = nm_dedup_multi_objs_to_ptr_array_head(nm_ip6_config_lookup_routes(self), NULL, NULL);
-
- routes_prune =
- nm_platform_ip_route_get_prune_list(platform, AF_INET6, ifindex, route_table_sync);
-
- nm_platform_ip6_address_sync(platform, ifindex, addresses, FALSE);
-
- if (!nm_platform_ip_route_sync(platform,
- AF_INET6,
- ifindex,
- routes,
- routes_prune,
- out_temporary_not_available))
- success = FALSE;
-
- return success;
-}
-
-void
-nm_ip6_config_merge_setting(NMIP6Config * self,
- NMSettingIPConfig *setting,
- guint32 route_table,
- guint32 route_metric)
-{
- guint naddresses, nroutes, nnameservers, nsearches;
- const char * gateway_str;
- struct in6_addr gateway_bin;
- int i, priority;
-
- if (!setting)
- return;
-
- g_return_if_fail(NM_IS_SETTING_IP6_CONFIG(setting));
-
- naddresses = nm_setting_ip_config_get_num_addresses(setting);
- nroutes = nm_setting_ip_config_get_num_routes(setting);
- nnameservers = nm_setting_ip_config_get_num_dns(setting);
- nsearches = nm_setting_ip_config_get_num_dns_searches(setting);
-
- g_object_freeze_notify(G_OBJECT(self));
-
- /* Gateway */
- if (!nm_setting_ip_config_get_never_default(setting)
- && (gateway_str = nm_setting_ip_config_get_gateway(setting))
- && inet_pton(AF_INET6, gateway_str, &gateway_bin) == 1
- && !IN6_IS_ADDR_UNSPECIFIED(&gateway_bin)) {
- const NMPlatformIP6Route r = {
- .rt_source = NM_IP_CONFIG_SOURCE_USER,
- .gateway = gateway_bin,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = route_metric,
- };
-
- _add_route(self, NULL, &r, NULL);
- }
-
- /* Addresses */
- for (i = 0; i < naddresses; i++) {
- NMIPAddress * s_addr = nm_setting_ip_config_get_address(setting, i);
- NMPlatformIP6Address address;
-
- memset(&address, 0, sizeof(address));
- nm_ip_address_get_address_binary(s_addr, &address.address);
- address.plen = nm_ip_address_get_prefix(s_addr);
- nm_assert(address.plen <= 128);
- address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
- address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
- address.addr_source = NM_IP_CONFIG_SOURCE_USER;
-
- _add_address(self, NULL, &address);
- }
-
- /* Routes */
- for (i = 0; i < nroutes; i++) {
- NMIPRoute * s_route = nm_setting_ip_config_get_route(setting, i);
- NMPlatformIP6Route route;
- gint64 m;
-
- if (nm_ip_route_get_family(s_route) != AF_INET6) {
- nm_assert_not_reached();
- continue;
- }
-
- memset(&route, 0, sizeof(route));
- nm_ip_route_get_dest_binary(s_route, &route.network);
-
- route.plen = nm_ip_route_get_prefix(s_route);
- nm_assert(route.plen <= 128);
-
- nm_ip_route_get_next_hop_binary(s_route, &route.gateway);
- m = nm_ip_route_get_metric(s_route);
- if (m < 0)
- route.metric = route_metric;
- else
- route.metric = nm_utils_ip6_route_metric_normalize(m);
- route.rt_source = NM_IP_CONFIG_SOURCE_USER;
-
- nm_utils_ip6_address_clear_host_address(&route.network, &route.network, route.plen);
-
- nm_utils_ip_route_attribute_to_platform(AF_INET6,
- s_route,
- NM_PLATFORM_IP_ROUTE_CAST(&route),
- route_table);
- _add_route(self, NULL, &route, NULL);
- }
-
- /* DNS */
- if (nm_setting_ip_config_get_ignore_auto_dns(setting)) {
- nm_ip6_config_reset_nameservers(self);
- nm_ip6_config_reset_domains(self);
- nm_ip6_config_reset_searches(self);
- }
- for (i = 0; i < nnameservers; i++) {
- struct in6_addr ip;
-
- if (inet_pton(AF_INET6, nm_setting_ip_config_get_dns(setting, i), &ip) == 1)
- nm_ip6_config_add_nameserver(self, &ip);
- }
- for (i = 0; i < nsearches; i++)
- nm_ip6_config_add_search(self, nm_setting_ip_config_get_dns_search(setting, i));
-
- i = 0;
- while ((i = nm_setting_ip_config_next_valid_dns_option(setting, i)) >= 0) {
- nm_ip6_config_add_dns_option(self, nm_setting_ip_config_get_dns_option(setting, i));
- i++;
- }
-
- priority = nm_setting_ip_config_get_dns_priority(setting);
- if (priority)
- nm_ip6_config_set_dns_priority(self, priority);
-
- nm_ip6_config_set_never_default(self, nm_setting_ip_config_get_never_default(setting));
-
- g_object_thaw_notify(G_OBJECT(self));
-}
-
-NMSetting *
-nm_ip6_config_create_setting(const NMIP6Config *self, gboolean maybe_ipv6_disabled)
-{
- const NMIP6ConfigPrivate * priv;
- NMSettingIPConfig * s_ip6;
- guint nnameservers, nsearches, noptions;
- const char * method = NULL;
- char sbuf[NM_UTILS_INET_ADDRSTRLEN];
- int i;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *address;
- const NMPlatformIP6Route * route;
-
- s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
-
- if (!self) {
- g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
- return NM_SETTING(s_ip6);
- }
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- nnameservers = nm_ip6_config_get_num_nameservers(self);
- nsearches = nm_ip6_config_get_num_searches(self);
- noptions = nm_ip6_config_get_num_dns_options(self);
-
- /* Addresses */
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &address) {
- NMIPAddress *s_addr;
-
- /* Ignore link-local address. */
- if (IN6_IS_ADDR_LINKLOCAL(&address->address)) {
- if (!method)
- method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
- continue;
- }
-
- /* Detect dynamic address */
- if (address->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
- method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
- continue;
- }
-
- /* Static address found. */
- if (!method || strcmp(method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0)
- method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
-
- s_addr = nm_ip_address_new_binary(AF_INET6, &address->address, address->plen, NULL);
- nm_setting_ip_config_add_address(s_ip6, s_addr);
- nm_ip_address_unref(s_addr);
- }
-
- /* Gateway */
- if (priv->best_default_route && nm_setting_ip_config_get_num_addresses(s_ip6) > 0) {
- g_object_set(
- s_ip6,
- NM_SETTING_IP_CONFIG_GATEWAY,
- _nm_utils_inet6_ntop(&NMP_OBJECT_CAST_IP6_ROUTE(priv->best_default_route)->gateway,
- sbuf),
- NULL);
- }
-
- /* Use 'ignore' if the method wasn't previously set */
- if (!method) {
- method = maybe_ipv6_disabled ? NM_SETTING_IP6_CONFIG_METHOD_DISABLED
- : NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
- }
-
- g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, method, NULL);
-
- /* Routes */
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, &route) {
- NMIPRoute *s_route;
-
- /* Ignore link-local route. */
- if (IN6_IS_ADDR_LINKLOCAL(&route->network))
- continue;
-
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route))
- continue;
-
- /* Ignore routes provided by external sources */
- if (route->rt_source
- != nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER))
- continue;
-
- s_route = nm_ip_route_new_binary(AF_INET6,
- &route->network,
- route->plen,
- &route->gateway,
- route->metric,
- NULL);
- nm_setting_ip_config_add_route(s_ip6, s_route);
- nm_ip_route_unref(s_route);
- }
-
- /* DNS */
- for (i = 0; i < nnameservers; i++) {
- const struct in6_addr *nameserver = nm_ip6_config_get_nameserver(self, i);
-
- nm_setting_ip_config_add_dns(s_ip6, _nm_utils_inet6_ntop(nameserver, sbuf));
- }
- for (i = 0; i < nsearches; i++) {
- const char *search = nm_ip6_config_get_search(self, i);
-
- nm_setting_ip_config_add_dns_search(s_ip6, search);
- }
- for (i = 0; i < noptions; i++) {
- const char *option = nm_ip6_config_get_dns_option(self, i);
-
- nm_setting_ip_config_add_dns_option(s_ip6, option);
- }
-
- g_object_set(s_ip6,
- NM_SETTING_IP_CONFIG_DNS_PRIORITY,
- nm_ip6_config_get_dns_priority(self),
- NULL);
-
- return NM_SETTING(s_ip6);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_merge(NMIP6Config * dst,
- const NMIP6Config * src,
- NMIPConfigMergeFlags merge_flags,
- guint32 default_route_metric_penalty)
-{
- guint32 i;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *address = NULL;
- const NMIP6ConfigPrivate * src_priv;
-
- g_return_if_fail(src != NULL);
- g_return_if_fail(dst != NULL);
-
- src_priv = NM_IP6_CONFIG_GET_PRIVATE(src);
-
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* addresses */
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, src, &address) {
- if (NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_EXTERNAL) && !address->external) {
- NMPlatformIP6Address a;
-
- a = *address;
- a.external = TRUE;
- _add_address(dst, NULL, &a);
- } else
- _add_address(dst, NMP_OBJECT_UP_CAST(address), NULL);
- }
-
- /* nameservers */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip6_config_get_num_nameservers(src); i++)
- nm_ip6_config_add_nameserver(dst, nm_ip6_config_get_nameserver(src, i));
- }
-
- /* routes */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
- const NMPlatformIP6Route *r_src;
-
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r_src) {
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r_src)) {
- if (NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES)
- && !NM_FLAGS_HAS(src_priv->config_flags,
- NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES))
- continue;
- if (default_route_metric_penalty) {
- NMPlatformIP6Route r = *r_src;
-
- r.metric =
- nm_utils_ip_route_metric_penalize(r.metric, default_route_metric_penalty);
- _add_route(dst, NULL, &r, NULL);
- continue;
- }
- }
- _add_route(dst, ipconf_iter.current->obj, NULL, NULL);
- }
- }
-
- /* domains */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip6_config_get_num_domains(src); i++)
- nm_ip6_config_add_domain(dst, nm_ip6_config_get_domain(src, i));
- }
-
- /* dns searches */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip6_config_get_num_searches(src); i++)
- nm_ip6_config_add_search(dst, nm_ip6_config_get_search(src, i));
- }
-
- /* dns options */
- if (!NM_FLAGS_HAS(merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
- for (i = 0; i < nm_ip6_config_get_num_dns_options(src); i++)
- nm_ip6_config_add_dns_option(dst, nm_ip6_config_get_dns_option(src, i));
- }
-
- /* DNS priority */
- if (nm_ip6_config_get_dns_priority(src))
- nm_ip6_config_set_dns_priority(dst, nm_ip6_config_get_dns_priority(src));
-
- g_object_thaw_notify(G_OBJECT(dst));
-}
-
-/*****************************************************************************/
-
-static int
-_nameservers_get_index(const NMIP6Config *self, const struct in6_addr *ns)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->nameservers->len; i++) {
- const struct in6_addr *n = &g_array_index(priv->nameservers, struct in6_addr, i);
-
- if (IN6_ARE_ADDR_EQUAL(ns, n))
- return (int) i;
- }
- return -1;
-}
-
-static int
-_domains_get_index(const NMIP6Config *self, const char *domain)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->domains->len; i++) {
- const char *d = g_ptr_array_index(priv->domains, i);
-
- if (g_strcmp0(domain, d) == 0)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_searches_get_index(const NMIP6Config *self, const char *search)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->searches->len; i++) {
- const char *s = g_ptr_array_index(priv->searches, i);
-
- if (g_strcmp0(search, s) == 0)
- return (int) i;
- }
- return -1;
-}
-
-static int
-_dns_options_get_index(const NMIP6Config *self, const char *option)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- guint i;
-
- for (i = 0; i < priv->dns_options->len; i++) {
- const char *s = g_ptr_array_index(priv->dns_options, i);
-
- if (g_strcmp0(option, s) == 0)
- return (int) i;
- }
- return -1;
-}
-
-/*****************************************************************************/
-
-/**
- * nm_ip6_config_subtract:
- * @dst: config from which to remove everything in @src
- * @src: config to remove from @dst
- * @default_route_metric_penalty: pretend that on source we applied
- * a route penalty on the default-route. It means, for default routes
- * we don't remove routes that match exactly, but those with a lower
- * metric (with the penalty removed).
-*
- * Removes everything in @src from @dst.
- */
-void
-nm_ip6_config_subtract(NMIP6Config * dst,
- const NMIP6Config *src,
- guint32 default_route_metric_penalty)
-{
- NMIP6ConfigPrivate * dst_priv;
- guint i;
- int idx;
- const NMPlatformIP6Address *a;
- const NMPlatformIP6Route * r;
- NMDedupMultiIter ipconf_iter;
- gboolean changed;
- gboolean changed_default_route;
-
- g_return_if_fail(src != NULL);
- g_return_if_fail(dst != NULL);
-
- dst_priv = NM_IP6_CONFIG_GET_PRIVATE(dst);
-
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* addresses */
- changed = FALSE;
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, src, &a) {
- if (nm_dedup_multi_index_remove_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip6_addresses,
- NMP_OBJECT_UP_CAST(a),
- NULL))
- changed = TRUE;
- }
- if (changed)
- _notify_addresses(dst);
-
- /* nameservers */
- for (i = 0; i < nm_ip6_config_get_num_nameservers(src); i++) {
- idx = _nameservers_get_index(dst, nm_ip6_config_get_nameserver(src, i));
- if (idx >= 0)
- nm_ip6_config_del_nameserver(dst, idx);
- }
-
- /* routes */
- changed = FALSE;
- changed_default_route = FALSE;
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r) {
- const NMPObject * o_src = NMP_OBJECT_UP_CAST(r);
- NMPObject o_lookup_copy;
- const NMPObject * o_lookup;
- nm_auto_nmpobj const NMPObject *obj_old = NULL;
-
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) && default_route_metric_penalty) {
- NMPlatformIP6Route *rr;
-
- /* the default route was penalized when merging it to the combined ip-config.
- * When subtracting the routes, we must re-do that process when comparing
- * the routes. */
- o_lookup = nmp_object_stackinit_obj(&o_lookup_copy, o_src);
- rr = NMP_OBJECT_CAST_IP6_ROUTE(&o_lookup_copy);
- rr->metric =
- nm_utils_ip_route_metric_penalize(rr->metric, default_route_metric_penalty);
- } else
- o_lookup = o_src;
-
- if (nm_dedup_multi_index_remove_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip6_routes,
- o_lookup,
- (gconstpointer *) &obj_old)) {
- if (dst_priv->best_default_route == obj_old) {
- nm_clear_nmp_object(&dst_priv->best_default_route);
- changed_default_route = TRUE;
- }
- changed = TRUE;
- }
- }
- if (changed_default_route) {
- nmp_object_ref_set(&dst_priv->best_default_route,
- _nm_ip6_config_best_default_route_find(dst));
- _notify(dst, PROP_GATEWAY);
- }
- if (changed)
- _notify_routes(dst);
-
- /* domains */
- for (i = 0; i < nm_ip6_config_get_num_domains(src); i++) {
- idx = _domains_get_index(dst, nm_ip6_config_get_domain(src, i));
- if (idx >= 0)
- nm_ip6_config_del_domain(dst, idx);
- }
-
- /* dns searches */
- for (i = 0; i < nm_ip6_config_get_num_searches(src); i++) {
- idx = _searches_get_index(dst, nm_ip6_config_get_search(src, i));
- if (idx >= 0)
- nm_ip6_config_del_search(dst, idx);
- }
-
- /* dns options */
- for (i = 0; i < nm_ip6_config_get_num_dns_options(src); i++) {
- idx = _dns_options_get_index(dst, nm_ip6_config_get_dns_option(src, i));
- if (idx >= 0)
- nm_ip6_config_del_dns_option(dst, idx);
- }
-
- /* DNS priority */
- if (nm_ip6_config_get_dns_priority(src) == nm_ip6_config_get_dns_priority(dst))
- nm_ip6_config_set_dns_priority(dst, 0);
-
- g_object_thaw_notify(G_OBJECT(dst));
-}
-
-static gboolean
-_nm_ip6_config_intersect_helper(NMIP6Config * dst,
- const NMIP6Config *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty,
- gboolean update_dst)
-{
- NMIP6ConfigPrivate * dst_priv;
- const NMIP6ConfigPrivate * src_priv;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *a;
- const NMPlatformIP6Route * r;
- gboolean changed, result = FALSE;
- const NMPObject * new_best_default_route;
-
- g_return_val_if_fail(src, FALSE);
- g_return_val_if_fail(dst, FALSE);
-
- dst_priv = NM_IP6_CONFIG_GET_PRIVATE(dst);
- src_priv = NM_IP6_CONFIG_GET_PRIVATE(src);
-
- if (update_dst)
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* addresses */
- if (intersect_addresses) {
- changed = FALSE;
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, dst, &a) {
- if (nm_dedup_multi_index_lookup_obj(src_priv->multi_idx,
- &src_priv->idx_ip6_addresses,
- NMP_OBJECT_UP_CAST(a)))
- continue;
-
- if (!update_dst)
- return TRUE;
-
- if (nm_dedup_multi_index_remove_entry(dst_priv->multi_idx, ipconf_iter.current) != 1)
- nm_assert_not_reached();
- changed = TRUE;
- }
- if (changed) {
- _notify_addresses(dst);
- result = TRUE;
- }
- }
-
- /* ignore nameservers */
-
- /* routes */
- if (!intersect_routes)
- goto skip_routes;
-
- changed = FALSE;
- new_best_default_route = NULL;
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, dst, &r) {
- const NMPObject *o_dst = NMP_OBJECT_UP_CAST(r);
- const NMPObject *o_lookup;
- NMPObject o_lookup_copy;
-
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) && default_route_metric_penalty) {
- NMPlatformIP6Route *rr;
-
- /* the default route was penalized when merging it to the combined ip-config.
- * When intersecting the routes, we must re-do that process when comparing
- * the routes. */
- o_lookup = nmp_object_stackinit_obj(&o_lookup_copy, o_dst);
- rr = NMP_OBJECT_CAST_IP6_ROUTE(&o_lookup_copy);
- rr->metric =
- nm_utils_ip_route_metric_penalize(rr->metric, default_route_metric_penalty);
- } else
- o_lookup = o_dst;
-
- if (nm_dedup_multi_index_lookup_obj(src_priv->multi_idx,
- &src_priv->idx_ip6_routes,
- o_lookup)) {
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route, o_dst);
- continue;
- }
-
- if (!update_dst)
- return TRUE;
-
- if (nm_dedup_multi_index_remove_entry(dst_priv->multi_idx, ipconf_iter.current) != 1)
- nm_assert_not_reached();
- changed = TRUE;
- }
- if (nmp_object_ref_set(&dst_priv->best_default_route, new_best_default_route)) {
- nm_assert(changed);
- _notify(dst, PROP_GATEWAY);
- }
- if (changed) {
- _notify_routes(dst);
- result = TRUE;
- }
-
-skip_routes:
- /* ignore domains */
- /* ignore dns searches */
- /* ignore dns options */
-
- if (update_dst)
- g_object_thaw_notify(G_OBJECT(dst));
-
- return result;
-}
-
-/**
- * nm_ip6_config_intersect:
- * @dst: a configuration to be updated
- * @src: another configuration
- * @intersect_addresses: whether addresses should be intersected
- * @intersect_routes: whether routes should be intersected
- * @default_route_metric_penalty: the default route metric penalty
- *
- * Computes the intersection between @src and @dst and updates @dst in place
- * with the result.
- */
-void
-nm_ip6_config_intersect(NMIP6Config * dst,
- const NMIP6Config *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty)
-{
- _nm_ip6_config_intersect_helper(dst,
- src,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty,
- TRUE);
-}
-
-/**
- * nm_ip6_config_intersect_alloc:
- * @a: a configuration
- * @b: another configuration
- * @intersect_addresses: whether addresses should be intersected
- * @intersect_routes: whether routes should be intersected
- * @default_route_metric_penalty: the default route metric penalty
- *
- * Computes the intersection between @a and @b and returns the result in a newly
- * allocated configuration. As a special case, if @a and @b are identical (with
- * respect to the only properties considered - addresses and routes) the
- * functions returns NULL so that one of existing configuration can be reused
- * without allocation.
- *
- * Returns: the intersection between @a and @b, or %NULL if the result is equal
- * to @a and @b.
- */
-NMIP6Config *
-nm_ip6_config_intersect_alloc(const NMIP6Config *a,
- const NMIP6Config *b,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty)
-{
- NMIP6Config *a_copy;
-
- if (_nm_ip6_config_intersect_helper((NMIP6Config *) a,
- b,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty,
- FALSE)) {
- a_copy = nm_ip6_config_clone(a);
- _nm_ip6_config_intersect_helper(a_copy,
- b,
- intersect_addresses,
- intersect_routes,
- default_route_metric_penalty,
- TRUE);
- return a_copy;
- } else
- return NULL;
-}
-
-/**
- * nm_ip6_config_replace:
- * @dst: config which will be replaced with everything in @src
- * @src: config to copy over to @dst
- * @relevant_changes: return whether there are changes to the
- * destination object that are relevant. This is equal to
- * nm_ip6_config_equal() showing any difference.
- *
- * Replaces everything in @dst with @src so that the two configurations
- * contain the same content -- with the exception of the dbus path.
- *
- * Returns: whether the @dst instance changed in any way (including minor changes,
- * that are not signaled by the output parameter @relevant_changes).
- */
-gboolean
-nm_ip6_config_replace(NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes)
-{
-#if NM_MORE_ASSERTS
- gboolean config_equal;
-#endif
- gboolean has_minor_changes = FALSE, has_relevant_changes = FALSE, are_equal;
- guint i, num;
- NMIP6ConfigPrivate * dst_priv;
- const NMIP6ConfigPrivate * src_priv;
- NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
- const NMDedupMultiHeadEntry *head_entry_src;
- const NMPObject * new_best_default_route;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(src), FALSE);
- g_return_val_if_fail(NM_IS_IP6_CONFIG(dst), FALSE);
- g_return_val_if_fail(src != dst, FALSE);
-
-#if NM_MORE_ASSERTS
- config_equal = nm_ip6_config_equal(dst, src);
-#endif
-
- dst_priv = NM_IP6_CONFIG_GET_PRIVATE(dst);
- src_priv = NM_IP6_CONFIG_GET_PRIVATE(src);
-
- g_return_val_if_fail(src_priv->ifindex > 0, FALSE);
-
- g_object_freeze_notify(G_OBJECT(dst));
-
- /* ifindex */
- if (src_priv->ifindex != dst_priv->ifindex) {
- dst_priv->ifindex = src_priv->ifindex;
- has_minor_changes = TRUE;
- }
-
- /* addresses */
- head_entry_src = nm_ip6_config_lookup_addresses(src);
- nm_dedup_multi_iter_init(&ipconf_iter_src, head_entry_src);
- nm_ip_config_iter_ip6_address_init(&ipconf_iter_dst, dst);
- are_equal = TRUE;
- while (TRUE) {
- gboolean has;
- const NMPlatformIP6Address *r_src = NULL;
- const NMPlatformIP6Address *r_dst = NULL;
-
- has = nm_platform_dedup_multi_iter_next_ip6_address(&ipconf_iter_src, &r_src);
- if (has != nm_platform_dedup_multi_iter_next_ip6_address(&ipconf_iter_dst, &r_dst)) {
- are_equal = FALSE;
- has_relevant_changes = TRUE;
- break;
- }
- if (!has)
- break;
-
- if (nm_platform_ip6_address_cmp(r_src, r_dst) != 0) {
- are_equal = FALSE;
- if (!IN6_ARE_ADDR_EQUAL(&r_src->address, &r_dst->address) || r_src->plen != r_dst->plen
- || !IN6_ARE_ADDR_EQUAL(nm_platform_ip6_address_get_peer(r_src),
- nm_platform_ip6_address_get_peer(r_dst))) {
- has_relevant_changes = TRUE;
- break;
- }
- }
- }
- if (!are_equal) {
- has_minor_changes = TRUE;
- nm_dedup_multi_index_dirty_set_idx(dst_priv->multi_idx, &dst_priv->idx_ip6_addresses);
- nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
- _nm_ip_config_add_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip6_addresses_,
- dst_priv->ifindex,
- ipconf_iter_src.current->obj,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL);
- }
- nm_dedup_multi_index_dirty_remove_idx(dst_priv->multi_idx,
- &dst_priv->idx_ip6_addresses,
- FALSE);
- _notify_addresses(dst);
- }
-
- /* routes */
- head_entry_src = nm_ip6_config_lookup_routes(src);
- nm_dedup_multi_iter_init(&ipconf_iter_src, head_entry_src);
- nm_ip_config_iter_ip6_route_init(&ipconf_iter_dst, dst);
- are_equal = TRUE;
- while (TRUE) {
- gboolean has;
- const NMPlatformIP6Route *r_src = NULL;
- const NMPlatformIP6Route *r_dst = NULL;
-
- has = nm_platform_dedup_multi_iter_next_ip6_route(&ipconf_iter_src, &r_src);
- if (has != nm_platform_dedup_multi_iter_next_ip6_route(&ipconf_iter_dst, &r_dst)) {
- are_equal = FALSE;
- has_relevant_changes = TRUE;
- break;
- }
- if (!has)
- break;
-
- if (nm_platform_ip6_route_cmp_full(r_src, r_dst) != 0) {
- are_equal = FALSE;
- if (r_src->plen != r_dst->plen
- || !nm_utils_ip6_address_same_prefix(&r_src->network, &r_dst->network, r_src->plen)
- || r_src->metric != r_dst->metric
- || !IN6_ARE_ADDR_EQUAL(&r_src->gateway, &r_dst->gateway)) {
- has_relevant_changes = TRUE;
- break;
- }
- }
- }
- if (!are_equal) {
- has_minor_changes = TRUE;
- new_best_default_route = NULL;
- nm_dedup_multi_index_dirty_set_idx(dst_priv->multi_idx, &dst_priv->idx_ip6_routes);
- nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
- const NMPObject *o = ipconf_iter_src.current->obj;
- const NMPObject *obj_new;
-
- _nm_ip_config_add_obj(dst_priv->multi_idx,
- &dst_priv->idx_ip6_routes_,
- dst_priv->ifindex,
- o,
- NULL,
- FALSE,
- TRUE,
- NULL,
- &obj_new);
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route, obj_new);
- }
- nm_dedup_multi_index_dirty_remove_idx(dst_priv->multi_idx,
- &dst_priv->idx_ip6_routes,
- FALSE);
- if (nmp_object_ref_set(&dst_priv->best_default_route, new_best_default_route))
- _notify(dst, PROP_GATEWAY);
- _notify_routes(dst);
- }
-
- /* nameservers */
- num = nm_ip6_config_get_num_nameservers(src);
- are_equal = num == nm_ip6_config_get_num_nameservers(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (!IN6_ARE_ADDR_EQUAL(nm_ip6_config_get_nameserver(src, i),
- nm_ip6_config_get_nameserver(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip6_config_reset_nameservers(dst);
- for (i = 0; i < num; i++)
- nm_ip6_config_add_nameserver(dst, nm_ip6_config_get_nameserver(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* domains */
- num = nm_ip6_config_get_num_domains(src);
- are_equal = num == nm_ip6_config_get_num_domains(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (g_strcmp0(nm_ip6_config_get_domain(src, i), nm_ip6_config_get_domain(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip6_config_reset_domains(dst);
- for (i = 0; i < num; i++)
- nm_ip6_config_add_domain(dst, nm_ip6_config_get_domain(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* dns searches */
- num = nm_ip6_config_get_num_searches(src);
- are_equal = num == nm_ip6_config_get_num_searches(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (g_strcmp0(nm_ip6_config_get_search(src, i), nm_ip6_config_get_search(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip6_config_reset_searches(dst);
- for (i = 0; i < num; i++)
- nm_ip6_config_add_search(dst, nm_ip6_config_get_search(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* dns options */
- num = nm_ip6_config_get_num_dns_options(src);
- are_equal = num == nm_ip6_config_get_num_dns_options(dst);
- if (are_equal) {
- for (i = 0; i < num; i++) {
- if (g_strcmp0(nm_ip6_config_get_dns_option(src, i),
- nm_ip6_config_get_dns_option(dst, i))) {
- are_equal = FALSE;
- break;
- }
- }
- }
- if (!are_equal) {
- nm_ip6_config_reset_dns_options(dst);
- for (i = 0; i < num; i++)
- nm_ip6_config_add_dns_option(dst, nm_ip6_config_get_dns_option(src, i));
- has_relevant_changes = TRUE;
- }
-
- /* DNS priority */
- if (src_priv->dns_priority != dst_priv->dns_priority) {
- nm_ip6_config_set_dns_priority(dst, src_priv->dns_priority);
- has_minor_changes = TRUE;
- }
-
- if (src_priv->privacy != dst_priv->privacy) {
- nm_ip6_config_set_privacy(dst, src_priv->privacy);
- has_minor_changes = TRUE;
- }
-
-#if NM_MORE_ASSERTS
- /* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes
- * regardless of config_equal. But config_equal must correspond to has_relevant_changes. */
- nm_assert(config_equal == !has_relevant_changes);
-#endif
-
- g_object_thaw_notify(G_OBJECT(dst));
-
- if (relevant_changes)
- *relevant_changes = has_relevant_changes;
-
- return has_relevant_changes || has_minor_changes;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_reset_addresses_ndisc(NMIP6Config * self,
- const NMNDiscAddress *addresses,
- guint addresses_n,
- guint8 plen,
- guint32 ifa_flags)
-{
- NMIP6ConfigPrivate *priv;
- guint i;
- gboolean changed = FALSE;
- gint32 base_time_sec;
-
- g_return_if_fail(NM_IS_IP6_CONFIG(self));
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(priv->ifindex > 0);
-
- /* the base-timestamp doesn't matter it's only an anchor for the
- * expiry. However, try to re-use the same base-time for a while
- * by rounding it to 10000 seconds.
- *
- * That is because we deduplicate and NMPlatformIP6Address instances
- * so using the same timestamps is preferable. */
- base_time_sec = nm_utils_get_monotonic_timestamp_sec();
- base_time_sec = (base_time_sec / 10000) * 10000;
- base_time_sec = NM_MAX(1, base_time_sec);
-
- nm_dedup_multi_index_dirty_set_idx(priv->multi_idx, &priv->idx_ip6_addresses);
-
- for (i = 0; i < addresses_n; i++) {
- const NMNDiscAddress *ndisc_addr = &addresses[i];
- NMPObject obj;
- NMPlatformIP6Address *a;
-
- nmp_object_stackinit(&obj, NMP_OBJECT_TYPE_IP6_ADDRESS, NULL);
- a = NMP_OBJECT_CAST_IP6_ADDRESS(&obj);
- a->ifindex = priv->ifindex;
- a->address = ndisc_addr->address;
- a->plen = plen;
- a->timestamp = base_time_sec,
- a->lifetime = _nm_ndisc_lifetime_from_expiry(((gint64) base_time_sec) * 1000,
- ndisc_addr->expiry_msec,
- TRUE),
- a->preferred = _nm_ndisc_lifetime_from_expiry(((gint64) base_time_sec) * 1000,
- ndisc_addr->expiry_preferred_msec,
- TRUE),
- a->addr_source = NM_IP_CONFIG_SOURCE_NDISC;
- a->n_ifa_flags = ifa_flags;
-
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip6_addresses_,
- priv->ifindex,
- &obj,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL))
- changed = TRUE;
- }
-
- if (nm_dedup_multi_index_dirty_remove_idx(priv->multi_idx, &priv->idx_ip6_addresses, FALSE) > 0)
- changed = TRUE;
-
- if (changed)
- _notify_addresses(self);
-}
-
-void
-nm_ip6_config_reset_addresses(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip6_addresses) > 0)
- _notify_addresses(self);
-}
-
-static void
-_add_address(NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Address *new)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip6_addresses_,
- priv->ifindex,
- obj_new,
- (const NMPlatformObject *) new,
- TRUE,
- FALSE,
- NULL,
- NULL))
- _notify_addresses(self);
-}
-
-/**
- * nm_ip6_config_add_address:
- * @self: the #NMIP6Config
- * @new: the new address to add to @self
- *
- * Adds the new address to @self. If an address with the same basic properties
- * (address, prefix) already exists in @self, it is overwritten with the
- * lifetime and preferred of @new. The source is also overwritten by the source
- * from @new if that source is higher priority.
- */
-void
-nm_ip6_config_add_address(NMIP6Config *self, const NMPlatformIP6Address *new)
-{
- g_return_if_fail(self);
- g_return_if_fail(new);
- g_return_if_fail(new->plen <= 128);
- g_return_if_fail(NM_IP6_CONFIG_GET_PRIVATE(self)->ifindex > 0);
-
- _add_address(self, NULL, new);
-}
-
-void
-_nmtst_ip6_config_del_address(NMIP6Config *self, guint i)
-{
- const NMPlatformIP6Address *a;
-
- a = _nmtst_ip6_config_get_address(self, i);
- if (!nm_ip6_config_nmpobj_remove(self, NMP_OBJECT_UP_CAST(a)))
- g_assert_not_reached();
-}
-
-guint
-nm_ip6_config_get_num_addresses(const NMIP6Config *self)
-{
- const NMDedupMultiHeadEntry *head_entry;
-
- head_entry = nm_ip6_config_lookup_addresses(self);
- return head_entry ? head_entry->len : 0;
-}
-
-const NMPlatformIP6Address *
-nm_ip6_config_get_first_address(const NMIP6Config *self)
-{
- NMDedupMultiIter iter;
- const NMPlatformIP6Address *a = NULL;
-
- nm_ip_config_iter_ip6_address_for_each (&iter, self, &a)
- return a;
- return NULL;
-}
-
-const NMPlatformIP6Address *
-_nmtst_ip6_config_get_address(const NMIP6Config *self, guint i)
-{
- NMDedupMultiIter iter;
- const NMPlatformIP6Address *a = NULL;
- guint j;
-
- j = 0;
- nm_ip_config_iter_ip6_address_for_each (&iter, self, &a) {
- if (i == j)
- return a;
- j++;
- }
- g_return_val_if_reached(NULL);
-}
-
-const NMPlatformIP6Address *
-nm_ip6_config_lookup_address(const NMIP6Config *self, const struct in6_addr *addr)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- NMPObject obj_stack;
- const NMDedupMultiEntry * entry;
-
- nmp_object_stackinit_id_ip6_address(&obj_stack, priv->ifindex, addr);
- entry = nm_dedup_multi_index_lookup_obj(priv->multi_idx, &priv->idx_ip6_addresses, &obj_stack);
- return entry ? NMP_OBJECT_CAST_IP6_ADDRESS(entry->obj) : NULL;
-}
-
-const NMPlatformIP6Address *
-nm_ip6_config_find_first_address(const NMIP6Config *self, NMPlatformMatchFlags match_flag)
-{
- const NMPlatformIP6Address *addr;
- NMDedupMultiIter iter;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(self), NULL);
-
- nm_assert(!NM_FLAGS_ANY(
- match_flag,
- ~(NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)));
-
- nm_assert(NM_FLAGS_ANY(match_flag, NM_PLATFORM_MATCH_WITH_ADDRTYPE__ANY));
- nm_assert(NM_FLAGS_ANY(match_flag, NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY));
-
- nm_ip_config_iter_ip6_address_for_each (&iter, self, &addr) {
- if (nm_platform_ip6_address_match(addr, match_flag))
- return addr;
- }
- return NULL;
-}
-
-/**
- * nm_ip6_config_has_dad_pending_addresses
- * @self: configuration containing the addresses to check
- * @candidates: configuration with the list of addresses we are
- * interested in
- *
- * Check whether there are addresses with DAD pending in @self, that
- * are also contained in @candidates.
- *
- * Returns: %TRUE if at least one matching address was found, %FALSE
- * otherwise
- */
-gboolean
-nm_ip6_config_has_any_dad_pending(const NMIP6Config *self, const NMIP6Config *candidates)
-{
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *addr, *addr_c;
-
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &addr) {
- if (NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_TENTATIVE)
- && !NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_DADFAILED)
- && !NM_FLAGS_HAS(addr->n_ifa_flags, IFA_F_OPTIMISTIC)) {
- addr_c = nm_ip6_config_lookup_address(candidates, &addr->address);
- if (addr_c) {
- if (addr->plen == addr_c->plen)
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-/*****************************************************************************/
-
-static const NMDedupMultiEntry *
-_lookup_route(const NMIP6Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type)
-{
- const NMIP6ConfigPrivate *priv;
-
- nm_assert(NM_IS_IP6_CONFIG(self));
- nm_assert(NMP_OBJECT_GET_TYPE(needle) == NMP_OBJECT_TYPE_IP6_ROUTE);
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return _nm_ip_config_lookup_ip_route(priv->multi_idx, &priv->idx_ip6_routes_, needle, cmp_type);
-}
-
-void
-nm_ip6_config_reset_routes_ndisc(NMIP6Config * self,
- const NMNDiscGateway *gateways,
- guint gateways_n,
- const NMNDiscRoute * routes,
- guint routes_n,
- guint32 route_table,
- guint32 route_metric,
- gboolean kernel_support_rta_pref)
-{
- NMIP6ConfigPrivate *priv;
- guint i;
- gboolean changed = FALSE;
- const NMPObject * new_best_default_route;
-
- g_return_if_fail(NM_IS_IP6_CONFIG(self));
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(priv->ifindex > 0);
-
- nm_dedup_multi_index_dirty_set_idx(priv->multi_idx, &priv->idx_ip6_routes);
-
- new_best_default_route = NULL;
- for (i = 0; i < routes_n; i++) {
- const NMNDiscRoute *ndisc_route = &routes[i];
- NMPObject obj;
- const NMPObject * obj_new;
- NMPlatformIP6Route *r;
-
- nmp_object_stackinit(&obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
- r = NMP_OBJECT_CAST_IP6_ROUTE(&obj);
- r->ifindex = priv->ifindex;
- r->network = ndisc_route->network;
- r->plen = ndisc_route->plen;
- r->gateway = ndisc_route->gateway;
- r->rt_source = NM_IP_CONFIG_SOURCE_NDISC;
- r->table_coerced = nm_platform_route_table_coerce(route_table);
- r->metric = route_metric;
- r->rt_pref = ndisc_route->preference;
- nm_assert((NMIcmpv6RouterPref) r->rt_pref == ndisc_route->preference);
-
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip6_routes_,
- priv->ifindex,
- &obj,
- NULL,
- FALSE,
- TRUE,
- NULL,
- &obj_new))
- changed = TRUE;
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route, obj_new);
- }
-
- if (gateways_n) {
- const NMPObject * obj_new;
- NMPlatformIP6Route r = {
- .rt_source = NM_IP_CONFIG_SOURCE_NDISC,
- .ifindex = priv->ifindex,
- .table_coerced = nm_platform_route_table_coerce(route_table),
- .metric = route_metric,
- };
- const NMIcmpv6RouterPref first_pref = gateways[0].preference;
-
- for (i = 0; i < gateways_n; i++) {
- r.gateway = gateways[i].address;
- r.rt_pref = gateways[i].preference;
- nm_assert((NMIcmpv6RouterPref) r.rt_pref == gateways[i].preference);
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip6_routes_,
- priv->ifindex,
- NULL,
- (const NMPlatformObject *) &r,
- FALSE,
- TRUE,
- NULL,
- &obj_new))
- changed = TRUE;
- new_best_default_route =
- _nm_ip_config_best_default_route_find_better(new_best_default_route, obj_new);
-
- if (first_pref != gateways[i].preference && !kernel_support_rta_pref) {
- /* We are unable to configure a router preference. Hence, we skip all gateways
- * with a different preference from the first gateway. Note, that the gateways
- * are sorted in order of highest to lowest preference. */
- break;
- }
- }
- }
-
- if (nm_dedup_multi_index_dirty_remove_idx(priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0)
- changed = TRUE;
-
- if (nmp_object_ref_set(&priv->best_default_route, new_best_default_route)) {
- changed = TRUE;
- _notify(self, PROP_GATEWAY);
- }
-
- if (changed)
- _notify_routes(self);
-}
-
-void
-nm_ip6_config_reset_routes(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip6_routes) > 0) {
- if (nm_clear_nmp_object(&priv->best_default_route))
- _notify(self, PROP_GATEWAY);
- _notify_routes(self);
- }
-}
-
-static void
-_add_route(NMIP6Config * self,
- const NMPObject *obj_new,
- const NMPlatformIP6Route *new,
- const NMPObject **out_obj_new)
-{
- NMIP6ConfigPrivate * priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- nm_auto_nmpobj const NMPObject *obj_old = NULL;
- const NMPObject * obj_new_2;
-
- nm_assert((!new) != (!obj_new));
- nm_assert(!new || _route_valid(new));
- nm_assert(!obj_new || _route_valid(NMP_OBJECT_CAST_IP6_ROUTE(obj_new)));
-
- if (_nm_ip_config_add_obj(priv->multi_idx,
- &priv->idx_ip6_routes_,
- priv->ifindex,
- obj_new,
- (const NMPlatformObject *) new,
- TRUE,
- FALSE,
- &obj_old,
- &obj_new_2)) {
- gboolean changed_default_route = FALSE;
-
- if (priv->best_default_route == obj_old && obj_old != obj_new_2) {
- changed_default_route = TRUE;
- nm_clear_nmp_object(&priv->best_default_route);
- }
- NM_SET_OUT(out_obj_new, nmp_object_ref(obj_new_2));
- if (_nm_ip_config_best_default_route_merge(&priv->best_default_route, obj_new_2))
- changed_default_route = TRUE;
-
- if (changed_default_route)
- _notify(self, PROP_GATEWAY);
- _notify_routes(self);
- } else
- NM_SET_OUT(out_obj_new, nmp_object_ref(obj_new_2));
-}
-
-/**
- * nm_ip6_config_add_route:
- * @self: the #NMIP6Config
- * @new: the new route to add to @self
- * @out_obj_new: (allow-none) (out): the added route object. Must be unrefed
- * by caller.
- *
- * Adds the new route to @self. If a route with the same basic properties
- * (network, prefix) already exists in @self, it is overwritten including the
- * gateway and metric of @new. The source is also overwritten by the source
- * from @new if that source is higher priority.
- */
-void
-nm_ip6_config_add_route(NMIP6Config *self,
- const NMPlatformIP6Route *new,
- const NMPObject **out_obj_new)
-{
- g_return_if_fail(self);
- g_return_if_fail(new);
- g_return_if_fail(new->plen <= 128);
- g_return_if_fail(NM_IP6_CONFIG_GET_PRIVATE(self)->ifindex > 0);
-
- _add_route(self, NULL, new, out_obj_new);
-}
-
-void
-_nmtst_ip6_config_del_route(NMIP6Config *self, guint i)
-{
- const NMPlatformIP6Route *r;
-
- r = _nmtst_ip6_config_get_route(self, i);
- if (!nm_ip6_config_nmpobj_remove(self, NMP_OBJECT_UP_CAST(r)))
- g_assert_not_reached();
-}
-
-guint
-nm_ip6_config_get_num_routes(const NMIP6Config *self)
-{
- const NMDedupMultiHeadEntry *head_entry;
-
- head_entry = nm_ip6_config_lookup_routes(self);
- nm_assert(!head_entry || head_entry->len == c_list_length(&head_entry->lst_entries_head));
- return head_entry ? head_entry->len : 0;
-}
-
-const NMPlatformIP6Route *
-_nmtst_ip6_config_get_route(const NMIP6Config *self, guint i)
-{
- NMDedupMultiIter iter;
- const NMPlatformIP6Route *r = NULL;
- guint j;
-
- j = 0;
- nm_ip_config_iter_ip6_route_for_each (&iter, self, &r) {
- if (i == j)
- return r;
- j++;
- }
- g_return_val_if_reached(NULL);
-}
-
-const NMPlatformIP6Route *
-nm_ip6_config_get_direct_route_for_host(const NMIP6Config * self,
- const struct in6_addr *host,
- guint32 route_table)
-{
- const NMPlatformIP6Route *best_route = NULL;
- const NMPlatformIP6Route *item;
- NMDedupMultiIter ipconf_iter;
-
- g_return_val_if_fail(host && !IN6_IS_ADDR_UNSPECIFIED(host), NULL);
-
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, &item) {
- if (!IN6_IS_ADDR_UNSPECIFIED(&item->gateway))
- continue;
-
- if (best_route && best_route->plen > item->plen)
- continue;
-
- if (nm_platform_route_table_uncoerce(item->table_coerced, TRUE) != route_table)
- continue;
-
- if (!nm_utils_ip6_address_same_prefix(host, &item->network, item->plen))
- continue;
-
- if (best_route && best_route->metric <= item->metric)
- continue;
-
- best_route = item;
- }
- return best_route;
-}
-
-const NMPlatformIP6Address *
-nm_ip6_config_get_subnet_for_host(const NMIP6Config *self, const struct in6_addr *host)
-{
- NMDedupMultiIter iter;
- const NMPlatformIP6Address *item;
- const NMPlatformIP6Address *subnet = NULL;
- struct in6_addr subnet2, host2;
-
- g_return_val_if_fail(host && !IN6_IS_ADDR_UNSPECIFIED(host), NULL);
-
- nm_ip_config_iter_ip6_address_for_each (&iter, self, &item) {
- if (subnet && subnet->plen >= item->plen)
- continue;
-
- nm_utils_ip6_address_clear_host_address(&host2, host, item->plen);
- nm_utils_ip6_address_clear_host_address(&subnet2, &item->address, item->plen);
-
- if (IN6_ARE_ADDR_EQUAL(&subnet2, &host2))
- subnet = item;
- }
-
- return subnet;
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_reset_nameservers(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (priv->nameservers->len != 0) {
- g_array_set_size(priv->nameservers, 0);
- _notify(self, PROP_NAMESERVERS);
- }
-}
-
-void
-nm_ip6_config_add_nameserver(NMIP6Config *self, const struct in6_addr *new)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- int i;
-
- g_return_if_fail(new != NULL);
-
- for (i = 0; i < priv->nameservers->len; i++)
- if (IN6_ARE_ADDR_EQUAL(new, &g_array_index(priv->nameservers, struct in6_addr, i)))
- return;
-
- g_array_append_val(priv->nameservers, *new);
- _notify(self, PROP_NAMESERVERS);
-}
-
-void
-nm_ip6_config_del_nameserver(NMIP6Config *self, guint i)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->nameservers->len);
-
- g_array_remove_index(priv->nameservers, i);
- _notify(self, PROP_NAMESERVERS);
-}
-
-guint
-nm_ip6_config_get_num_nameservers(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return priv->nameservers->len;
-}
-
-const struct in6_addr *
-nm_ip6_config_get_nameserver(const NMIP6Config *self, guint i)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return &g_array_index(priv->nameservers, struct in6_addr, i);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_reset_domains(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (priv->domains->len != 0) {
- g_ptr_array_set_size(priv->domains, 0);
- _notify(self, PROP_DOMAINS);
- }
-}
-
-void
-nm_ip6_config_add_domain(NMIP6Config *self, const char *domain)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (_nm_ip_config_check_and_add_domain(priv->domains, domain))
- _notify(self, PROP_DOMAINS);
-}
-
-void
-nm_ip6_config_del_domain(NMIP6Config *self, guint i)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->domains->len);
-
- g_ptr_array_remove_index(priv->domains, i);
- _notify(self, PROP_DOMAINS);
-}
-
-guint
-nm_ip6_config_get_num_domains(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return priv->domains->len;
-}
-
-const char *
-nm_ip6_config_get_domain(const NMIP6Config *self, guint i)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return g_ptr_array_index(priv->domains, i);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_reset_searches(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (priv->searches->len != 0) {
- g_ptr_array_set_size(priv->searches, 0);
- _notify(self, PROP_SEARCHES);
- }
-}
-
-void
-nm_ip6_config_add_search(NMIP6Config *self, const char *search)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (_nm_ip_config_check_and_add_domain(priv->searches, search))
- _notify(self, PROP_SEARCHES);
-}
-
-void
-nm_ip6_config_del_search(NMIP6Config *self, guint i)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->searches->len);
-
- g_ptr_array_remove_index(priv->searches, i);
- _notify(self, PROP_SEARCHES);
-}
-
-guint
-nm_ip6_config_get_num_searches(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return priv->searches->len;
-}
-
-const char *
-nm_ip6_config_get_search(const NMIP6Config *self, guint i)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return g_ptr_array_index(priv->searches, i);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_reset_dns_options(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (priv->dns_options->len != 0) {
- g_ptr_array_set_size(priv->dns_options, 0);
- _notify(self, PROP_DNS_OPTIONS);
- }
-}
-
-void
-nm_ip6_config_add_dns_option(NMIP6Config *self, const char *new)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- int i;
-
- g_return_if_fail(new != NULL);
- g_return_if_fail(new[0] != '\0');
-
- for (i = 0; i < priv->dns_options->len; i++)
- if (!g_strcmp0(g_ptr_array_index(priv->dns_options, i), new))
- return;
-
- g_ptr_array_add(priv->dns_options, g_strdup(new));
- _notify(self, PROP_DNS_OPTIONS);
-}
-
-void
-nm_ip6_config_del_dns_option(NMIP6Config *self, guint i)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- g_return_if_fail(i < priv->dns_options->len);
-
- g_ptr_array_remove_index(priv->dns_options, i);
- _notify(self, PROP_DNS_OPTIONS);
-}
-
-guint
-nm_ip6_config_get_num_dns_options(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return priv->dns_options->len;
-}
-
-const char *
-nm_ip6_config_get_dns_option(const NMIP6Config *self, guint i)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return g_ptr_array_index(priv->dns_options, i);
-}
-
-/*****************************************************************************/
-
-NMIPConfigFlags
-nm_ip6_config_get_config_flags(const NMIP6Config *self)
-{
- return NM_IP6_CONFIG_GET_PRIVATE(self)->config_flags;
-}
-
-void
-nm_ip6_config_set_config_flags(NMIP6Config *self, NMIPConfigFlags flags, NMIPConfigFlags mask)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (mask == 0) {
- /* for convenience, accept 0 mask to set any flags. */
- mask = flags;
- }
-
- nm_assert(!NM_FLAGS_ANY(flags, ~mask));
- priv->config_flags = (flags & mask) | (priv->config_flags & ~mask);
-}
-
-/*****************************************************************************/
-
-void
-nm_ip6_config_set_dns_priority(NMIP6Config *self, int priority)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- if (priority != priv->dns_priority) {
- priv->dns_priority = priority;
- _notify(self, PROP_DNS_PRIORITY);
- }
-}
-
-int
-nm_ip6_config_get_dns_priority(const NMIP6Config *self)
-{
- const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- return priv->dns_priority;
-}
-
-/*****************************************************************************/
-
-const NMPObject *
-nm_ip6_config_nmpobj_lookup(const NMIP6Config *self, const NMPObject *needle)
-{
- const NMIP6ConfigPrivate * priv;
- const NMDedupMultiIdxType *idx_type;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(self), NULL);
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- switch (NMP_OBJECT_GET_TYPE(needle)) {
- case NMP_OBJECT_TYPE_IP6_ADDRESS:
- idx_type = &priv->idx_ip6_addresses;
- break;
- case NMP_OBJECT_TYPE_IP6_ROUTE:
- idx_type = &priv->idx_ip6_routes;
- break;
- default:
- g_return_val_if_reached(NULL);
- }
-
- return nm_dedup_multi_entry_get_obj(
- nm_dedup_multi_index_lookup_obj(priv->multi_idx, idx_type, needle));
-}
-
-gboolean
-nm_ip6_config_nmpobj_remove(NMIP6Config *self, const NMPObject *needle)
-{
- NMIP6ConfigPrivate * priv;
- NMDedupMultiIdxType *idx_type;
- nm_auto_nmpobj const NMPObject *obj_old = NULL;
- guint n;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(self), FALSE);
-
- priv = NM_IP6_CONFIG_GET_PRIVATE(self);
- switch (NMP_OBJECT_GET_TYPE(needle)) {
- case NMP_OBJECT_TYPE_IP6_ADDRESS:
- idx_type = &priv->idx_ip6_addresses;
- break;
- case NMP_OBJECT_TYPE_IP6_ROUTE:
- idx_type = &priv->idx_ip6_routes;
- break;
- default:
- g_return_val_if_reached(FALSE);
- }
-
- n = nm_dedup_multi_index_remove_obj(priv->multi_idx,
- idx_type,
- needle,
- (gconstpointer *) &obj_old);
- if (n != 1) {
- nm_assert(n == 0);
- return FALSE;
- }
-
- nm_assert(NMP_OBJECT_GET_TYPE(obj_old) == NMP_OBJECT_GET_TYPE(needle));
-
- switch (NMP_OBJECT_GET_TYPE(obj_old)) {
- case NMP_OBJECT_TYPE_IP6_ADDRESS:
- _notify_addresses(self);
- break;
- case NMP_OBJECT_TYPE_IP6_ROUTE:
- if (priv->best_default_route == obj_old) {
- if (nmp_object_ref_set(&priv->best_default_route,
- _nm_ip6_config_best_default_route_find(self)))
- _notify(self, PROP_GATEWAY);
- }
- _notify_routes(self);
- break;
- default:
- nm_assert_not_reached();
- }
- return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-hash_u32(GChecksum *sum, guint32 n)
-{
- g_checksum_update(sum, (const guint8 *) &n, sizeof(n));
-}
-
-static void
-hash_in6addr(GChecksum *sum, const struct in6_addr *a)
-{
- if (a)
- g_checksum_update(sum, (const guint8 *) a, sizeof(*a));
- else
- g_checksum_update(sum, (const guint8 *) &in6addr_any, sizeof(in6addr_any));
-}
-
-void
-nm_ip6_config_hash(const NMIP6Config *self, GChecksum *sum, gboolean dns_only)
-{
- guint32 i;
- const char * s;
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Address *address;
- const NMPlatformIP6Route * route;
-
- g_return_if_fail(self);
- g_return_if_fail(sum);
-
- if (dns_only == FALSE) {
- nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &address) {
- hash_in6addr(sum, &address->address);
- hash_u32(sum, address->plen);
- }
-
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, &route) {
- hash_in6addr(sum, &route->network);
- hash_u32(sum, route->plen);
- hash_in6addr(sum, &route->gateway);
- hash_u32(sum, route->metric);
- }
- }
-
- for (i = 0; i < nm_ip6_config_get_num_nameservers(self); i++)
- hash_in6addr(sum, nm_ip6_config_get_nameserver(self, i));
-
- for (i = 0; i < nm_ip6_config_get_num_domains(self); i++) {
- s = nm_ip6_config_get_domain(self, i);
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-
- for (i = 0; i < nm_ip6_config_get_num_searches(self); i++) {
- s = nm_ip6_config_get_search(self, i);
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-
- for (i = 0; i < nm_ip6_config_get_num_dns_options(self); i++) {
- s = nm_ip6_config_get_dns_option(self, i);
- g_checksum_update(sum, (const guint8 *) s, strlen(s));
- }
-}
-
-/**
- * nm_ip6_config_equal:
- * @a: first config to compare
- * @b: second config to compare
- *
- * Compares two #NMIP6Configs for basic equality. This means that all
- * attributes must exist in the same order in both configs (addresses, routes,
- * domains, DNS servers, etc) but some attributes (address lifetimes, and address
- * and route sources) are ignored.
- *
- * Returns: %TRUE if the configurations are basically equal to each other,
- * %FALSE if not
- */
-gboolean
-nm_ip6_config_equal(const NMIP6Config *a, const NMIP6Config *b)
-{
- nm_auto_free_checksum GChecksum *a_checksum = g_checksum_new(G_CHECKSUM_SHA1);
- nm_auto_free_checksum GChecksum *b_checksum = g_checksum_new(G_CHECKSUM_SHA1);
- guint8 a_data[NM_UTILS_CHECKSUM_LENGTH_SHA1];
- guint8 b_data[NM_UTILS_CHECKSUM_LENGTH_SHA1];
-
- if (a)
- nm_ip6_config_hash(a, a_checksum, FALSE);
- if (b)
- nm_ip6_config_hash(b, b_checksum, FALSE);
-
- nm_utils_checksum_get_digest(a_checksum, a_data);
- nm_utils_checksum_get_digest(b_checksum, b_data);
- return !memcmp(a_data, b_data, sizeof(a_data));
-}
-
-/*****************************************************************************/
-
-static void
-nameservers_to_gvalue(GArray *array, GValue *value)
-{
- GVariantBuilder builder;
- guint i = 0;
-
- g_variant_builder_init(&builder, G_VARIANT_TYPE("aay"));
-
- while (array && (i < array->len)) {
- struct in6_addr *addr;
-
- addr = &g_array_index(array, struct in6_addr, i++);
- g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(addr));
- }
-
- g_value_take_variant(value, g_variant_builder_end(&builder));
-}
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- NMIP6Config * self = NM_IP6_CONFIG(object);
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- switch (prop_id) {
- case PROP_IFINDEX:
- g_value_set_int(value, priv->ifindex);
- break;
- case PROP_ADDRESS_DATA:
- case PROP_ADDRESSES:
- nm_assert(!!priv->address_data_variant == !!priv->addresses_variant);
-
- if (!priv->address_data_variant) {
- nm_utils_ip_addresses_to_dbus(AF_INET6,
- nm_ip6_config_lookup_addresses(self),
- priv->best_default_route,
- priv->privacy,
- &priv->address_data_variant,
- &priv->addresses_variant);
- g_variant_ref_sink(priv->address_data_variant);
- g_variant_ref_sink(priv->addresses_variant);
- }
- g_value_set_variant(value,
- prop_id == PROP_ADDRESS_DATA ? priv->address_data_variant
- : priv->addresses_variant);
- break;
-
- case PROP_ROUTE_DATA:
- case PROP_ROUTES:
- nm_assert(!!priv->route_data_variant == !!priv->routes_variant);
-
- if (!priv->route_data_variant) {
- nm_utils_ip_routes_to_dbus(AF_INET6,
- nm_ip6_config_lookup_routes(self),
- &priv->route_data_variant,
- &priv->routes_variant);
- g_variant_ref_sink(priv->route_data_variant);
- g_variant_ref_sink(priv->routes_variant);
- }
-
- g_value_set_variant(value,
- prop_id == PROP_ROUTE_DATA ? priv->route_data_variant
- : priv->routes_variant);
- break;
- case PROP_GATEWAY:
- if (priv->best_default_route) {
- g_value_take_string(value,
- nm_utils_inet6_ntop_dup(
- &NMP_OBJECT_CAST_IP6_ROUTE(priv->best_default_route)->gateway));
- } else
- g_value_set_string(value, NULL);
- break;
- case PROP_NAMESERVERS:
- nameservers_to_gvalue(priv->nameservers, value);
- break;
- case PROP_DOMAINS:
- nm_utils_g_value_set_strv(value, priv->domains);
- break;
- case PROP_SEARCHES:
- nm_utils_g_value_set_strv(value, priv->searches);
- break;
- case PROP_DNS_OPTIONS:
- nm_utils_g_value_set_strv(value, priv->dns_options);
- break;
- case PROP_DNS_PRIORITY:
- g_value_set_int(value, priv->dns_priority);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- NMIP6Config * self = NM_IP6_CONFIG(object);
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- switch (prop_id) {
- case PROP_MULTI_IDX:
- /* construct-only */
- priv->multi_idx = g_value_get_pointer(value);
- if (!priv->multi_idx)
- g_return_if_reached();
- nm_dedup_multi_index_ref(priv->multi_idx);
- break;
- case PROP_IFINDEX:
- /* construct-only */
- priv->ifindex = g_value_get_int(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-/*****************************************************************************/
-
-static void
-nm_ip6_config_init(NMIP6Config *self)
-{
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip6_addresses,
- NMP_OBJECT_TYPE_IP6_ADDRESS);
- nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip6_routes,
- NMP_OBJECT_TYPE_IP6_ROUTE);
-
- priv->nameservers = g_array_new(FALSE, TRUE, sizeof(struct in6_addr));
- priv->domains = g_ptr_array_new_with_free_func(g_free);
- priv->searches = g_ptr_array_new_with_free_func(g_free);
- priv->dns_options = g_ptr_array_new_with_free_func(g_free);
-}
-
-NMIP6Config *
-nm_ip6_config_new(NMDedupMultiIndex *multi_idx, int ifindex)
-{
- g_return_val_if_fail(ifindex >= -1, NULL);
- return g_object_new(NM_TYPE_IP6_CONFIG,
- NM_IP6_CONFIG_MULTI_IDX,
- multi_idx,
- NM_IP6_CONFIG_IFINDEX,
- ifindex,
- NULL);
-}
-
-NMIP6Config *
-nm_ip6_config_new_cloned(const NMIP6Config *src)
-{
- NMIP6Config *new;
-
- g_return_val_if_fail(NM_IS_IP6_CONFIG(src), NULL);
-
- new = nm_ip6_config_new(nm_ip6_config_get_multi_idx(src), nm_ip6_config_get_ifindex(src));
- nm_ip6_config_replace(new, src, NULL);
- return new;
-}
-
-static void
-finalize(GObject *object)
-{
- NMIP6Config * self = NM_IP6_CONFIG(object);
- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE(self);
-
- nm_clear_nmp_object(&priv->best_default_route);
-
- nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip6_addresses);
- nm_dedup_multi_index_remove_idx(priv->multi_idx, &priv->idx_ip6_routes);
-
- nm_clear_g_variant(&priv->address_data_variant);
- nm_clear_g_variant(&priv->addresses_variant);
- nm_clear_g_variant(&priv->route_data_variant);
- nm_clear_g_variant(&priv->routes_variant);
-
- g_array_unref(priv->nameservers);
- g_ptr_array_unref(priv->domains);
- g_ptr_array_unref(priv->searches);
- g_ptr_array_unref(priv->dns_options);
-
- G_OBJECT_CLASS(nm_ip6_config_parent_class)->finalize(object);
-
- nm_dedup_multi_index_unref(priv->multi_idx);
-}
-
-static const NMDBusInterfaceInfoExtended interface_info_ip6_config = {
- .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
- NM_DBUS_INTERFACE_IP6_CONFIG,
- .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Addresses",
- "a(ayuay)",
- NM_IP6_CONFIG_ADDRESSES),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AddressData",
- "aa{sv}",
- NM_IP6_CONFIG_ADDRESS_DATA),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Gateway", "s", NM_IP6_CONFIG_GATEWAY),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Routes",
- "a(ayuayu)",
- NM_IP6_CONFIG_ROUTES),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RouteData",
- "aa{sv}",
- NM_IP6_CONFIG_ROUTE_DATA),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Nameservers",
- "aay",
- NM_IP6_CONFIG_NAMESERVERS),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Domains", "as", NM_IP6_CONFIG_DOMAINS),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Searches",
- "as",
- NM_IP6_CONFIG_SEARCHES),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsOptions",
- "as",
- NM_IP6_CONFIG_DNS_OPTIONS),
- NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DnsPriority",
- "i",
- NM_IP6_CONFIG_DNS_PRIORITY), ), ),
-};
-
-static void
-nm_ip6_config_class_init(NMIP6ConfigClass *klass)
-{
- GObjectClass * object_class = G_OBJECT_CLASS(klass);
- NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
- NMIPConfigClass * ip_config_class = NM_IP_CONFIG_CLASS(klass);
-
- ip_config_class->is_ipv4 = FALSE;
- ip_config_class->addr_family = AF_INET6;
-
- dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/IP6Config");
- dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_ip6_config);
-
- object_class->get_property = get_property;
- object_class->set_property = set_property;
- object_class->finalize = finalize;
-
- obj_properties[PROP_MULTI_IDX] =
- g_param_spec_pointer(NM_IP6_CONFIG_MULTI_IDX,
- "",
- "",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_IFINDEX] =
- g_param_spec_int(NM_IP6_CONFIG_IFINDEX,
- "",
- "",
- -1,
- G_MAXINT,
- -1,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ADDRESS_DATA] =
- g_param_spec_variant(NM_IP6_CONFIG_ADDRESS_DATA,
- "",
- "",
- G_VARIANT_TYPE("aa{sv}"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ADDRESSES] =
- g_param_spec_variant(NM_IP6_CONFIG_ADDRESSES,
- "",
- "",
- G_VARIANT_TYPE("a(ayuay)"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ROUTE_DATA] =
- g_param_spec_variant(NM_IP6_CONFIG_ROUTE_DATA,
- "",
- "",
- G_VARIANT_TYPE("aa{sv}"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ROUTES] = g_param_spec_variant(NM_IP6_CONFIG_ROUTES,
- "",
- "",
- G_VARIANT_TYPE("a(ayuayu)"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_GATEWAY] = g_param_spec_string(NM_IP6_CONFIG_GATEWAY,
- "",
- "",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_NAMESERVERS] =
- g_param_spec_variant(NM_IP6_CONFIG_NAMESERVERS,
- "",
- "",
- G_VARIANT_TYPE("aay"),
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DOMAINS] = g_param_spec_boxed(NM_IP6_CONFIG_DOMAINS,
- "",
- "",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_SEARCHES] = g_param_spec_boxed(NM_IP6_CONFIG_SEARCHES,
- "",
- "",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DNS_OPTIONS] =
- g_param_spec_boxed(NM_IP6_CONFIG_DNS_OPTIONS,
- "",
- "",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DNS_PRIORITY] = g_param_spec_int(NM_IP6_CONFIG_DNS_PRIORITY,
- "",
- "",
- G_MININT32,
- G_MAXINT32,
- 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-}
diff --git a/src/core/nm-ip6-config.h b/src/core/nm-ip6-config.h
deleted file mode 100644
index 4aa0ee4e58..0000000000
--- a/src/core/nm-ip6-config.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2008 - 2013 Red Hat, Inc.
- */
-
-#ifndef __NETWORKMANAGER_IP6_CONFIG_H__
-#define __NETWORKMANAGER_IP6_CONFIG_H__
-
-#include <netinet/in.h>
-
-#include "nm-setting-ip6-config.h"
-
-#include "libnm-glib-aux/nm-dedup-multi.h"
-#include "libnm-platform/nmp-object.h"
-#include "nm-ip-config.h"
-
-/*****************************************************************************/
-
-void nm_ip_config_iter_ip6_address_init(NMDedupMultiIter *iter, const NMIP6Config *self);
-void nm_ip_config_iter_ip6_route_init(NMDedupMultiIter *iter, const NMIP6Config *self);
-
-#define nm_ip_config_iter_ip6_address_for_each(iter, self, address) \
- for (nm_ip_config_iter_ip6_address_init((iter), (self)); \
- nm_platform_dedup_multi_iter_next_ip6_address((iter), (address));)
-
-#define nm_ip_config_iter_ip6_route_for_each(iter, self, route) \
- for (nm_ip_config_iter_ip6_route_init((iter), (self)); \
- nm_platform_dedup_multi_iter_next_ip6_route((iter), (route));)
-
-/*****************************************************************************/
-
-#define NM_TYPE_IP6_CONFIG (nm_ip6_config_get_type())
-#define NM_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IP6_CONFIG, NMIP6Config))
-#define NM_IP6_CONFIG_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass))
-#define NM_IS_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_IP6_CONFIG))
-#define NM_IS_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_IP6_CONFIG))
-#define NM_IP6_CONFIG_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass))
-
-typedef struct _NMIP6ConfigClass NMIP6ConfigClass;
-
-/* internal */
-#define NM_IP6_CONFIG_MULTI_IDX "multi-idx"
-#define NM_IP6_CONFIG_IFINDEX "ifindex"
-
-/* public */
-#define NM_IP6_CONFIG_ADDRESS_DATA "address-data"
-#define NM_IP6_CONFIG_ROUTE_DATA "route-data"
-#define NM_IP6_CONFIG_GATEWAY "gateway"
-#define NM_IP6_CONFIG_NAMESERVERS "nameservers"
-#define NM_IP6_CONFIG_DOMAINS "domains"
-#define NM_IP6_CONFIG_SEARCHES "searches"
-#define NM_IP6_CONFIG_DNS_OPTIONS "dns-options"
-#define NM_IP6_CONFIG_DNS_PRIORITY "dns-priority"
-
-/* deprecated */
-#define NM_IP6_CONFIG_ADDRESSES "addresses"
-#define NM_IP6_CONFIG_ROUTES "routes"
-
-GType nm_ip6_config_get_type(void);
-
-NMIP6Config *nm_ip6_config_new(struct _NMDedupMultiIndex *multi_idx, int ifindex);
-NMIP6Config *nm_ip6_config_new_cloned(const NMIP6Config *src);
-
-NMIP6Config *nm_ip6_config_clone(const NMIP6Config *self);
-int nm_ip6_config_get_ifindex(const NMIP6Config *self);
-
-struct _NMDedupMultiIndex *nm_ip6_config_get_multi_idx(const NMIP6Config *self);
-
-NMIP6Config *nm_ip6_config_capture(struct _NMDedupMultiIndex *multi_idx,
- NMPlatform * platform,
- int ifindex,
- NMSettingIP6ConfigPrivacy use_temporary);
-
-void nm_ip6_config_add_dependent_routes(NMIP6Config *self,
- guint32 route_table,
- guint32 route_metric,
- gboolean is_vrf);
-
-gboolean nm_ip6_config_commit(const NMIP6Config * self,
- NMPlatform * platform,
- NMIPRouteTableSyncMode route_table_sync,
- GPtrArray ** out_temporary_not_available);
-void nm_ip6_config_merge_setting(NMIP6Config * self,
- NMSettingIPConfig *setting,
- guint32 route_table,
- guint32 route_metric);
-NMSetting *nm_ip6_config_create_setting(const NMIP6Config *self, gboolean maybe_ipv6_disabled);
-
-void nm_ip6_config_merge(NMIP6Config * dst,
- const NMIP6Config * src,
- NMIPConfigMergeFlags merge_flags,
- guint32 default_route_metric_penalty);
-void nm_ip6_config_subtract(NMIP6Config * dst,
- const NMIP6Config *src,
- guint32 default_route_metric_penalty);
-void nm_ip6_config_intersect(NMIP6Config * dst,
- const NMIP6Config *src,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty);
-NMIP6Config *nm_ip6_config_intersect_alloc(const NMIP6Config *a,
- const NMIP6Config *b,
- gboolean intersect_addresses,
- gboolean intersect_routes,
- guint32 default_route_metric_penalty);
-gboolean
-nm_ip6_config_replace(NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes);
-
-const NMPObject *nm_ip6_config_best_default_route_get(const NMIP6Config *self);
-const NMPObject *_nm_ip6_config_best_default_route_find(const NMIP6Config *self);
-
-enum _NMIPConfigFlags;
-
-void nm_ip6_config_set_config_flags(NMIP6Config * self,
- enum _NMIPConfigFlags flags,
- enum _NMIPConfigFlags mask);
-enum _NMIPConfigFlags nm_ip6_config_get_config_flags(const NMIP6Config *self);
-
-const NMDedupMultiHeadEntry *nm_ip6_config_lookup_addresses(const NMIP6Config *self);
-void nm_ip6_config_reset_addresses(NMIP6Config *self);
-void nm_ip6_config_add_address(NMIP6Config *self, const NMPlatformIP6Address *address);
-void _nmtst_ip6_config_del_address(NMIP6Config *self, guint i);
-guint nm_ip6_config_get_num_addresses(const NMIP6Config *self);
-const NMPlatformIP6Address *nm_ip6_config_get_first_address(const NMIP6Config *self);
-const NMPlatformIP6Address *_nmtst_ip6_config_get_address(const NMIP6Config *self, guint i);
-const NMPlatformIP6Address *nm_ip6_config_find_first_address(const NMIP6Config * self,
- NMPlatformMatchFlags match_flag);
-gboolean nm_ip6_config_address_exists(const NMIP6Config *self, const NMPlatformIP6Address *address);
-const NMPlatformIP6Address *nm_ip6_config_lookup_address(const NMIP6Config * self,
- const struct in6_addr *addr);
-gboolean _nmtst_ip6_config_addresses_sort(NMIP6Config *self);
-gboolean nm_ip6_config_has_any_dad_pending(const NMIP6Config *self, const NMIP6Config *candidates);
-
-const NMDedupMultiHeadEntry *nm_ip6_config_lookup_routes(const NMIP6Config *self);
-void nm_ip6_config_reset_routes(NMIP6Config *self);
-void nm_ip6_config_add_route(NMIP6Config * self,
- const NMPlatformIP6Route *route,
- const NMPObject ** out_obj_new);
-void _nmtst_ip6_config_del_route(NMIP6Config *self, guint i);
-guint nm_ip6_config_get_num_routes(const NMIP6Config *self);
-const NMPlatformIP6Route * _nmtst_ip6_config_get_route(const NMIP6Config *self, guint i);
-
-const NMPlatformIP6Route * nm_ip6_config_get_direct_route_for_host(const NMIP6Config * self,
- const struct in6_addr *host,
- guint32 route_table);
-const NMPlatformIP6Address *nm_ip6_config_get_subnet_for_host(const NMIP6Config * self,
- const struct in6_addr *host);
-
-void nm_ip6_config_reset_nameservers(NMIP6Config *self);
-void nm_ip6_config_add_nameserver(NMIP6Config *self, const struct in6_addr *nameserver);
-void nm_ip6_config_del_nameserver(NMIP6Config *self, guint i);
-guint nm_ip6_config_get_num_nameservers(const NMIP6Config *self);
-const struct in6_addr *nm_ip6_config_get_nameserver(const NMIP6Config *self, guint i);
-
-void nm_ip6_config_reset_domains(NMIP6Config *self);
-void nm_ip6_config_add_domain(NMIP6Config *self, const char *domain);
-void nm_ip6_config_del_domain(NMIP6Config *self, guint i);
-guint nm_ip6_config_get_num_domains(const NMIP6Config *self);
-const char *nm_ip6_config_get_domain(const NMIP6Config *self, guint i);
-
-void nm_ip6_config_reset_searches(NMIP6Config *self);
-void nm_ip6_config_add_search(NMIP6Config *self, const char *search);
-void nm_ip6_config_del_search(NMIP6Config *self, guint i);
-guint nm_ip6_config_get_num_searches(const NMIP6Config *self);
-const char *nm_ip6_config_get_search(const NMIP6Config *self, guint i);
-
-void nm_ip6_config_reset_dns_options(NMIP6Config *self);
-void nm_ip6_config_add_dns_option(NMIP6Config *self, const char *option);
-void nm_ip6_config_del_dns_option(NMIP6Config *self, guint i);
-guint nm_ip6_config_get_num_dns_options(const NMIP6Config *self);
-const char *nm_ip6_config_get_dns_option(const NMIP6Config *self, guint i);
-
-void nm_ip6_config_set_dns_priority(NMIP6Config *self, int priority);
-int nm_ip6_config_get_dns_priority(const NMIP6Config *self);
-
-void nm_ip6_config_set_never_default(NMIP6Config *self, gboolean never_default);
-gboolean nm_ip6_config_get_never_default(const NMIP6Config *self);
-
-const NMPObject *nm_ip6_config_nmpobj_lookup(const NMIP6Config *self, const NMPObject *needle);
-gboolean nm_ip6_config_nmpobj_remove(NMIP6Config *self, const NMPObject *needle);
-
-void nm_ip6_config_hash(const NMIP6Config *self, GChecksum *sum, gboolean dns_only);
-gboolean nm_ip6_config_equal(const NMIP6Config *a, const NMIP6Config *b);
-
-void nm_ip6_config_set_privacy(NMIP6Config *self, NMSettingIP6ConfigPrivacy privacy);
-
-struct _NMNDiscAddress;
-void nm_ip6_config_reset_addresses_ndisc(NMIP6Config * self,
- const struct _NMNDiscAddress *addresses,
- guint addresses_n,
- guint8 plen,
- guint32 ifa_flags);
-struct _NMNDiscRoute;
-struct _NMNDiscGateway;
-void nm_ip6_config_reset_routes_ndisc(NMIP6Config * self,
- const struct _NMNDiscGateway *gateways,
- guint gateways_n,
- const struct _NMNDiscRoute * routes,
- guint routes_n,
- guint32 route_table,
- guint32 route_metric,
- gboolean kernel_support_rta_pref);
-
-void nm_ip6_config_update_routes_metric(NMIP6Config *self, gint64 metric);
-
-#endif /* __NETWORKMANAGER_IP6_CONFIG_H__ */
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index 419ce88dfe..35e95d0c21 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -2605,8 +2605,6 @@ get_existing_connection(NMManager *self, NMDevice *device, gboolean *out_generat
if (out_generated)
*out_generated = FALSE;
- nm_device_capture_initial_config(device);
-
if (ifindex) {
int master_ifindex = nm_platform_link_get_master(priv->platform, ifindex);
diff --git a/src/core/nm-pacrunner-manager.c b/src/core/nm-pacrunner-manager.c
index 67930dbae0..acf9269eb9 100644
--- a/src/core/nm-pacrunner-manager.c
+++ b/src/core/nm-pacrunner-manager.c
@@ -7,15 +7,14 @@
#include "nm-pacrunner-manager.h"
-#include "nm-utils.h"
-#include "NetworkManagerUtils.h"
-#include "libnm-platform/nm-platform.h"
-#include "nm-dbus-manager.h"
-#include "nm-proxy-config.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
#include "c-list/src/c-list.h"
#include "libnm-glib-aux/nm-dbus-aux.h"
+#include "libnm-platform/nm-platform.h"
+
+#include "NetworkManagerUtils.h"
+#include "nm-dbus-manager.h"
+#include "nm-l3-config-data.h"
+#include "nm-utils.h"
#define PACRUNNER_DBUS_SERVICE "org.pacrunner"
#define PACRUNNER_DBUS_INTERFACE "org.pacrunner.Manager"
@@ -124,58 +123,50 @@ NM_AUTO_DEFINE_FCN0(NMPacrunnerConfId *, _nm_auto_unref_conf_id, conf_id_unref);
/*****************************************************************************/
static void
-get_ip_domains(GPtrArray *domains, NMIPConfig *ip_config)
+get_ip_domains(GPtrArray *domains, const NML3ConfigData *l3cd, int addr_family)
{
NMDedupMultiIter ipconf_iter;
char * cidr;
- guint i, num;
+ guint num;
+ guint i;
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
- int addr_family;
const NMPlatformIPAddress *address;
- const NMPlatformIPRoute * routes;
-
- if (!ip_config)
- return;
+ const NMPlatformIPRoute * route;
+ const char *const * strv;
- addr_family = nm_ip_config_get_addr_family(ip_config);
-
- num = nm_ip_config_get_num_searches(ip_config);
+ strv = nm_l3_config_data_get_searches(l3cd, addr_family, &num);
for (i = 0; i < num; i++)
- g_ptr_array_add(domains, g_strdup(nm_ip_config_get_search(ip_config, i)));
+ g_ptr_array_add(domains, g_strdup(strv[i]));
- num = nm_ip_config_get_num_domains(ip_config);
+ strv = nm_l3_config_data_get_domains(l3cd, addr_family, &num);
for (i = 0; i < num; i++)
- g_ptr_array_add(domains, g_strdup(nm_ip_config_get_domain(ip_config, i)));
+ g_ptr_array_add(domains, g_strdup(strv[i]));
- nm_ip_config_iter_ip_address_for_each (&ipconf_iter, ip_config, &address) {
+ nm_l3_config_data_iter_ip_address_for_each (&ipconf_iter, l3cd, addr_family, &address) {
cidr = g_strdup_printf("%s/%u",
nm_utils_inet_ntop(addr_family, address->address_ptr, sbuf),
address->plen);
g_ptr_array_add(domains, cidr);
}
- nm_ip_config_iter_ip_route_for_each (&ipconf_iter, ip_config, &routes) {
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(routes))
+ nm_l3_config_data_iter_ip_route_for_each (&ipconf_iter, l3cd, addr_family, &route) {
+ if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route))
continue;
cidr = g_strdup_printf("%s/%u",
- nm_utils_inet_ntop(addr_family, routes->network_ptr, sbuf),
- routes->plen);
+ nm_utils_inet_ntop(addr_family, route->network_ptr, sbuf),
+ route->plen);
g_ptr_array_add(domains, cidr);
}
}
static GVariant *
-_make_request_create_proxy_configuration(NMProxyConfig *proxy_config,
- const char * iface,
- NMIP4Config * ip4_config,
- NMIP6Config * ip6_config)
+_make_request_create_proxy_configuration(const char *iface, const NML3ConfigData *l3cd)
{
GVariantBuilder builder;
NMProxyConfigMethod method;
- const char * pac_url;
- const char * pac_script;
+ const char * s;
- nm_assert(NM_IS_PROXY_CONFIG(proxy_config));
+ nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
@@ -183,20 +174,18 @@ _make_request_create_proxy_configuration(NMProxyConfig *proxy_config,
g_variant_builder_add(&builder, "{sv}", "Interface", g_variant_new_string(iface));
}
- method = nm_proxy_config_get_method(proxy_config);
+ method = nm_l3_config_data_get_proxy_method(l3cd);
switch (method) {
case NM_PROXY_CONFIG_METHOD_AUTO:
g_variant_builder_add(&builder, "{sv}", "Method", g_variant_new_string("auto"));
- pac_url = nm_proxy_config_get_pac_url(proxy_config);
- if (pac_url) {
- g_variant_builder_add(&builder, "{sv}", "URL", g_variant_new_string(pac_url));
- }
+ s = nm_l3_config_data_get_proxy_pac_url(l3cd);
+ if (s)
+ g_variant_builder_add(&builder, "{sv}", "URL", g_variant_new_string(s));
- pac_script = nm_proxy_config_get_pac_script(proxy_config);
- if (pac_script) {
- g_variant_builder_add(&builder, "{sv}", "Script", g_variant_new_string(pac_script));
- }
+ s = nm_l3_config_data_get_proxy_pac_script(l3cd);
+ if (s)
+ g_variant_builder_add(&builder, "{sv}", "Script", g_variant_new_string(s));
break;
case NM_PROXY_CONFIG_METHOD_UNKNOWN:
case NM_PROXY_CONFIG_METHOD_NONE:
@@ -207,15 +196,15 @@ _make_request_create_proxy_configuration(NMProxyConfig *proxy_config,
g_variant_builder_add(&builder,
"{sv}",
"BrowserOnly",
- g_variant_new_boolean(nm_proxy_config_get_browser_only(proxy_config)));
+ g_variant_new_boolean(!!nm_l3_config_data_get_proxy_browser_only(l3cd)));
- if (ip4_config || ip6_config) {
+ if (l3cd) {
gs_unref_ptrarray GPtrArray *domains = NULL;
domains = g_ptr_array_new_with_free_func(g_free);
- get_ip_domains(domains, NM_IP_CONFIG_CAST(ip4_config));
- get_ip_domains(domains, NM_IP_CONFIG_CAST(ip6_config));
+ get_ip_domains(domains, l3cd, AF_INET);
+ get_ip_domains(domains, l3cd, AF_INET6);
if (domains->len > 0) {
g_variant_builder_add(
@@ -356,10 +345,8 @@ _try_start_service_by_name(NMPacrunnerManager *self)
/**
* nm_pacrunner_manager_add:
* @self: the #NMPacrunnerManager
- * @proxy_config: proxy config of the connection
* @iface: the iface for the connection or %NULL
- * @ip4_config: IP4 config of the connection to extract domain info from
- * @ip6_config: IP6 config of the connection to extract domain info from
+ * @l3cd: the #NML3ConfigData of the connection to extract domain info from
*
* Returns: a #NMPacrunnerConfId id. The function cannot
* fail and always returns a non NULL pointer. The conf-id may
@@ -367,18 +354,14 @@ _try_start_service_by_name(NMPacrunnerManager *self)
* Note that the conf-id keeps the @self instance alive.
*/
NMPacrunnerConfId *
-nm_pacrunner_manager_add(NMPacrunnerManager *self,
- NMProxyConfig * proxy_config,
- const char * iface,
- NMIP4Config * ip4_config,
- NMIP6Config * ip6_config)
+nm_pacrunner_manager_add(NMPacrunnerManager *self, const char *iface, const NML3ConfigData *l3cd)
{
NMPacrunnerManagerPrivate *priv;
NMPacrunnerConfId * conf_id;
gs_free char * log_msg = NULL;
g_return_val_if_fail(NM_IS_PACRUNNER_MANAGER(self), NULL);
- g_return_val_if_fail(proxy_config, NULL);
+ g_return_val_if_fail(NM_IS_L3_CONFIG_DATA(l3cd), NULL);
priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self);
@@ -387,8 +370,7 @@ nm_pacrunner_manager_add(NMPacrunnerManager *self,
.log_id = ++priv->log_id_counter,
.refcount = 1,
.self = g_object_ref(self),
- .parameters = g_variant_ref_sink(
- _make_request_create_proxy_configuration(proxy_config, iface, ip4_config, ip6_config)),
+ .parameters = g_variant_ref_sink(_make_request_create_proxy_configuration(iface, l3cd)),
};
c_list_link_tail(&priv->conf_id_lst_head, &conf_id->conf_id_lst);
diff --git a/src/core/nm-pacrunner-manager.h b/src/core/nm-pacrunner-manager.h
index fd40f1204d..3f16908f4e 100644
--- a/src/core/nm-pacrunner-manager.h
+++ b/src/core/nm-pacrunner-manager.h
@@ -26,11 +26,8 @@ GType nm_pacrunner_manager_get_type(void);
NMPacrunnerManager *nm_pacrunner_manager_get(void);
-NMPacrunnerConfId *nm_pacrunner_manager_add(NMPacrunnerManager *self,
- NMProxyConfig * proxy_config,
- const char * iface,
- NMIP4Config * ip4_config,
- NMIP6Config * ip6_config);
+NMPacrunnerConfId *
+nm_pacrunner_manager_add(NMPacrunnerManager *self, const char *iface, const NML3ConfigData *l3cd);
void nm_pacrunner_manager_remove(NMPacrunnerConfId *conf_id);
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
index c2ab9b2d0d..34dfc62abe 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -11,28 +11,31 @@
#include <unistd.h>
#include <netdb.h>
+#include "libnm-core-intern/nm-core-internal.h"
+#include "libnm-platform/nm-platform.h"
+#include "libnm-platform/nmp-object.h"
+
#include "NetworkManagerUtils.h"
-#include "nm-act-request.h"
-#include "nm-keep-alive.h"
#include "devices/nm-device.h"
-#include "nm-setting-ip4-config.h"
-#include "nm-setting-connection.h"
-#include "libnm-platform/nm-platform.h"
#include "dns/nm-dns-manager.h"
-#include "vpn/nm-vpn-manager.h"
+#include "nm-act-request.h"
#include "nm-auth-utils.h"
-#include "nm-firewalld-manager.h"
+#include "nm-config.h"
+#include "nm-dhcp-config.h"
#include "nm-dispatcher.h"
-#include "nm-utils.h"
-#include "libnm-core-intern/nm-core-internal.h"
+#include "nm-firewalld-manager.h"
+#include "nm-hostname-manager.h"
+#include "nm-keep-alive.h"
+#include "nm-l3-config-data.h"
#include "nm-manager.h"
-#include "settings/nm-settings.h"
-#include "settings/nm-settings-connection.h"
-#include "settings/nm-agent-manager.h"
-#include "nm-dhcp-config.h"
-#include "nm-config.h"
#include "nm-netns.h"
-#include "nm-hostname-manager.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-utils.h"
+#include "settings/nm-agent-manager.h"
+#include "settings/nm-settings-connection.h"
+#include "settings/nm-settings.h"
+#include "vpn/nm-vpn-manager.h"
/*****************************************************************************/
@@ -136,30 +139,6 @@ static NMDevice *get_default_device(NMPolicy *self, int addr_family);
/*****************************************************************************/
-static void
-_dns_manager_set_ip_config(NMDnsManager * dns_manager,
- NMIPConfig * ip_config,
- NMDnsIPConfigType ip_config_type,
- NMDevice * device)
-{
- if (device && nm_device_sys_iface_state_is_external(device)) {
- nm_dns_manager_set_ip_config(dns_manager, ip_config, NM_DNS_IP_CONFIG_TYPE_REMOVED);
- return;
- }
-
- if (NM_IN_SET(ip_config_type, NM_DNS_IP_CONFIG_TYPE_DEFAULT, NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE)
- && device
- && nm_device_get_route_metric_default(nm_device_get_device_type(device))
- == NM_VPN_ROUTE_METRIC_DEFAULT) {
- /* some device types are inherently VPN. */
- ip_config_type = NM_DNS_IP_CONFIG_TYPE_VPN;
- }
-
- nm_dns_manager_set_ip_config(dns_manager, ip_config, ip_config_type);
-}
-
-/*****************************************************************************/
-
typedef struct {
NMPlatformIP6Address prefix;
NMDevice * device; /* The requesting ("uplink") device */
@@ -971,7 +950,7 @@ update_default_ac(NMPolicy *self, int addr_family, NMActiveConnection *best)
nm_active_connection_set_default(best, addr_family, TRUE);
}
-static gpointer
+static const NML3ConfigData *
get_best_ip_config(NMPolicy * self,
int addr_family,
const char ** out_ip_iface,
@@ -979,20 +958,21 @@ get_best_ip_config(NMPolicy * self,
NMDevice ** out_device,
NMVpnConnection ** out_vpn)
{
- NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
- gpointer conf, best_conf = NULL;
- const CList * tmp_list;
- NMActiveConnection *ac;
- guint64 best_metric = G_MAXUINT64;
- NMVpnConnection * best_vpn = NULL;
+ NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
+ const NML3ConfigData *l3cd_best = NULL;
+ const CList * tmp_list;
+ NMActiveConnection * ac;
+ guint64 best_metric = G_MAXUINT64;
+ NMVpnConnection * best_vpn = NULL;
nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6));
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
- NMVpnConnection * candidate;
- NMVpnConnectionState vpn_state;
- const NMPObject * obj;
- guint32 metric;
+ const NML3ConfigData *l3cd;
+ NMVpnConnection * candidate;
+ NMVpnConnectionState vpn_state;
+ const NMPObject * obj;
+ guint32 metric;
if (!NM_IS_VPN_CONNECTION(ac))
continue;
@@ -1003,24 +983,18 @@ get_best_ip_config(NMPolicy * self,
if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED)
continue;
- if (addr_family == AF_INET)
- conf = nm_vpn_connection_get_ip4_config(candidate);
- else
- conf = nm_vpn_connection_get_ip6_config(candidate);
- if (!conf)
+ l3cd = nm_vpn_connection_get_l3cd(candidate, addr_family);
+ if (!l3cd)
continue;
- if (addr_family == AF_INET)
- obj = nm_ip4_config_best_default_route_get(conf);
- else
- obj = nm_ip6_config_best_default_route_get(conf);
+ obj = nm_l3_config_data_get_best_default_route(l3cd, addr_family);
if (!obj)
continue;
metric = NMP_OBJECT_CAST_IPX_ROUTE(obj)->rx.metric;
if (metric <= best_metric) {
best_metric = metric;
- best_conf = conf;
+ l3cd_best = l3cd;
best_vpn = candidate;
}
}
@@ -1030,25 +1004,20 @@ get_best_ip_config(NMPolicy * self,
NM_SET_OUT(out_vpn, best_vpn);
NM_SET_OUT(out_ac, NM_ACTIVE_CONNECTION(best_vpn));
NM_SET_OUT(out_ip_iface, nm_vpn_connection_get_ip_iface(best_vpn, TRUE));
- return best_conf;
+ return l3cd_best;
}
ac = get_best_active_connection(self, addr_family, TRUE);
if (ac) {
NMDevice *device = nm_active_connection_get_device(ac);
- nm_assert(device);
-
- if (addr_family == AF_INET)
- conf = nm_device_get_ip4_config(device);
- else
- conf = nm_device_get_ip6_config(device);
+ nm_assert(NM_IS_DEVICE(device));
NM_SET_OUT(out_device, device);
NM_SET_OUT(out_vpn, NULL);
NM_SET_OUT(out_ac, ac);
NM_SET_OUT(out_ip_iface, nm_device_get_ip_iface(device));
- return conf;
+ return nm_device_get_l3cd(device, TRUE);
}
NM_SET_OUT(out_device, NULL);
@@ -1066,8 +1035,6 @@ update_ip4_routing(NMPolicy *self, gboolean force_update)
NMVpnConnection * vpn = NULL;
NMActiveConnection *best_ac = NULL;
const char * ip_iface = NULL;
- const CList * tmp_list;
- NMActiveConnection *ac;
/* Note that we might have an IPv4 VPN tunneled over an IPv6-only device,
* so we can get (vpn != NULL && best == NULL).
@@ -1085,11 +1052,11 @@ update_ip4_routing(NMPolicy *self, gboolean force_update)
return;
if (best) {
- nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
- if (NM_IS_VPN_CONNECTION(ac) && nm_vpn_connection_get_ip4_config(NM_VPN_CONNECTION(ac))
- && !nm_active_connection_get_device(ac))
- nm_active_connection_set_device(ac, best);
- }
+ //XXX nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
+ //XXX if (NM_IS_VPN_CONNECTION(ac) && nm_vpn_connection_get_ip4_config(NM_VPN_CONNECTION(ac))
+ //XXX && !nm_active_connection_get_device(ac))
+ //XXX nm_active_connection_set_device(ac, best);
+ //XXX }
}
update_default_ac(self, AF_INET, best_ac);
@@ -1129,8 +1096,6 @@ update_ip6_routing(NMPolicy *self, gboolean force_update)
NMVpnConnection * vpn = NULL;
NMActiveConnection *best_ac = NULL;
const char * ip_iface = NULL;
- NMActiveConnection *ac;
- const CList * tmp_list;
/* Note that we might have an IPv6 VPN tunneled over an IPv4-only device,
* so we can get (vpn != NULL && best == NULL).
@@ -1148,11 +1113,11 @@ update_ip6_routing(NMPolicy *self, gboolean force_update)
return;
if (best) {
- nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
- if (NM_IS_VPN_CONNECTION(ac) && nm_vpn_connection_get_ip6_config(NM_VPN_CONNECTION(ac))
- && !nm_active_connection_get_device(ac))
- nm_active_connection_set_device(ac, best);
- }
+ //XXX nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
+ //XXX if (NM_IS_VPN_CONNECTION(ac) && nm_vpn_connection_get_ip6_config(NM_VPN_CONNECTION(ac))
+ //XXX && !nm_active_connection_get_device(ac))
+ //XXX nm_active_connection_set_device(ac, best);
+ //XXX }
}
update_default_ac(self, AF_INET6, best_ac);
@@ -1173,25 +1138,38 @@ update_ip6_routing(NMPolicy *self, gboolean force_update)
static void
update_ip_dns(NMPolicy *self, int addr_family, NMDevice *changed_device)
{
- NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
- gpointer ip_config;
- const char * ip_iface = NULL;
- NMVpnConnection *vpn = NULL;
- NMDevice * device = NULL;
+ NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self);
+ const NML3ConfigData *l3cd;
+ const char * ip_iface = NULL;
+ NMVpnConnection * vpn = NULL;
+ NMDevice * device = NULL;
nm_assert_addr_family(addr_family);
- ip_config = get_best_ip_config(self, addr_family, &ip_iface, NULL, &device, &vpn);
- if (ip_config) {
+ l3cd = get_best_ip_config(self, addr_family, &ip_iface, NULL, &device, &vpn);
+ if (l3cd) {
+ NMDnsIPConfigType ip_config_type;
+
+ nm_assert(!device || NM_IS_DEVICE(device));
+ nm_assert(!vpn || NM_IS_VPN_CONNECTION(vpn));
+ nm_assert((!!device) != (!!vpn));
+
/* Tell the DNS manager this config is preferred by re-adding it with
* a different IP config type.
*/
- _dns_manager_set_ip_config(NM_POLICY_GET_PRIVATE(self)->dns_manager,
- ip_config,
- (vpn || (device && nm_device_is_vpn(device)))
- ? NM_DNS_IP_CONFIG_TYPE_VPN
- : NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE,
- device);
+ if (device && nm_device_sys_iface_state_is_external(device))
+ ip_config_type = NM_DNS_IP_CONFIG_TYPE_REMOVED;
+ else if (vpn || (device && nm_device_is_vpn(device)))
+ ip_config_type = NM_DNS_IP_CONFIG_TYPE_VPN;
+ else
+ ip_config_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
+
+ nm_dns_manager_set_ip_config(NM_POLICY_GET_PRIVATE(self)->dns_manager,
+ addr_family,
+ ((gconstpointer) device) ?: ((gconstpointer) vpn),
+ l3cd,
+ ip_config_type,
+ TRUE);
}
if (addr_family == AF_INET6) {
@@ -1906,9 +1884,7 @@ device_state_changed(NMDevice * device,
NMPolicy * self = _PRIV_TO_SELF(priv);
NMActiveConnection * ac;
NMSettingsConnection *sett_conn = nm_device_get_settings_connection(device);
- NMIP4Config * ip4_config;
- NMIP6Config * ip6_config;
- NMSettingConnection * s_con = NULL;
+ NMSettingConnection * s_con = NULL;
switch (nm_device_state_reason_check(reason)) {
case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED:
@@ -2010,27 +1986,6 @@ device_state_changed(NMDevice * device,
/* Reset auto retries back to default since connection was successful */
nm_settings_connection_autoconnect_retries_reset(sett_conn);
}
-
- /* Add device's new IPv4 and IPv6 configs to DNS */
-
- nm_dns_manager_begin_updates(priv->dns_manager, __func__);
-
- ip4_config = nm_device_get_ip4_config(device);
- if (ip4_config)
- _dns_manager_set_ip_config(priv->dns_manager,
- NM_IP_CONFIG_CAST(ip4_config),
- NM_DNS_IP_CONFIG_TYPE_DEFAULT,
- device);
- ip6_config = nm_device_get_ip6_config(device);
- if (ip6_config)
- _dns_manager_set_ip_config(priv->dns_manager,
- NM_IP_CONFIG_CAST(ip6_config),
- NM_DNS_IP_CONFIG_TYPE_DEFAULT,
- device);
-
- update_routing_and_dns(self, FALSE, device);
-
- nm_dns_manager_end_updates(priv->dns_manager, __func__);
break;
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
@@ -2132,24 +2087,16 @@ device_state_changed(NMDevice * device,
}
static void
-device_ip_config_changed(NMDevice * device,
- NMIPConfig *new_config,
- NMIPConfig *old_config,
- gpointer user_data)
+device_l3cd_changed(NMDevice * device,
+ const NML3ConfigData *l3cd_old,
+ const NML3ConfigData *l3cd_new,
+ gpointer user_data)
{
NMPolicyPrivate *priv = user_data;
NMPolicy * self = _PRIV_TO_SELF(priv);
- int addr_family;
- nm_assert(new_config || old_config);
- nm_assert(!new_config || NM_IS_IP_CONFIG(new_config));
- nm_assert(!old_config || NM_IS_IP_CONFIG(old_config));
-
- if (new_config) {
- addr_family = nm_ip_config_get_addr_family(new_config);
- nm_assert(!old_config || addr_family == nm_ip_config_get_addr_family(old_config));
- } else
- addr_family = nm_ip_config_get_addr_family(old_config);
+ nm_assert(!l3cd_new || NM_IS_L3_CONFIG_DATA(l3cd_new));
+ nm_assert(!l3cd_old || NM_IS_L3_CONFIG_DATA(l3cd_old));
nm_dns_manager_begin_updates(priv->dns_manager, __func__);
@@ -2158,30 +2105,25 @@ device_ip_config_changed(NMDevice * device,
* ignore IP config changes but when the device is in activated state.
* Prevents unnecessary changes to DNS information.
*/
- if (nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) {
- if (old_config != new_config) {
- if (new_config)
- _dns_manager_set_ip_config(priv->dns_manager,
- new_config,
- NM_DNS_IP_CONFIG_TYPE_DEFAULT,
- device);
- if (old_config)
- nm_dns_manager_set_ip_config(priv->dns_manager,
- old_config,
- NM_DNS_IP_CONFIG_TYPE_REMOVED);
- }
- update_ip_dns(self, addr_family, device);
- if (addr_family == AF_INET)
- update_ip4_routing(self, TRUE);
- else
- update_ip6_routing(self, TRUE);
- update_system_hostname(self, addr_family == AF_INET ? "ip4 conf" : "ip6 conf");
+ if (nm_device_get_state(device) < NM_DEVICE_STATE_DEACTIVATING) {
+ nm_dns_manager_set_ip_config(priv->dns_manager,
+ AF_UNSPEC,
+ device,
+ l3cd_new,
+ NM_DNS_IP_CONFIG_TYPE_DEFAULT,
+ TRUE);
+ update_ip_dns(self, AF_INET, device);
+ update_ip_dns(self, AF_INET6, device);
+ update_ip4_routing(self, TRUE);
+ update_ip6_routing(self, TRUE);
+ update_system_hostname(self, "ip conf");
} else {
- /* Old configs get removed immediately */
- if (old_config)
- nm_dns_manager_set_ip_config(priv->dns_manager,
- old_config,
- NM_DNS_IP_CONFIG_TYPE_REMOVED);
+ nm_dns_manager_set_ip_config(priv->dns_manager,
+ AF_UNSPEC,
+ device,
+ l3cd_old,
+ NM_DNS_IP_CONFIG_TYPE_REMOVED,
+ TRUE);
}
nm_dns_manager_end_updates(priv->dns_manager, __func__);
@@ -2222,14 +2164,7 @@ devices_list_register(NMPolicy *self, NMDevice *device)
/* Connect state-changed with _after, so that the handler is invoked after other handlers. */
g_signal_connect_after(device, NM_DEVICE_STATE_CHANGED, (GCallback) device_state_changed, priv);
- g_signal_connect(device,
- NM_DEVICE_IP4_CONFIG_CHANGED,
- (GCallback) device_ip_config_changed,
- priv);
- g_signal_connect(device,
- NM_DEVICE_IP6_CONFIG_CHANGED,
- (GCallback) device_ip_config_changed,
- priv);
+ g_signal_connect(device, NM_DEVICE_L3CD_CHANGED, (GCallback) device_l3cd_changed, priv);
g_signal_connect(device,
NM_DEVICE_IP6_PREFIX_DELEGATED,
(GCallback) device_ip6_prefix_delegated,
@@ -2291,51 +2226,26 @@ device_removed(NMManager *manager, NMDevice *device, gpointer user_data)
/*****************************************************************************/
static void
-vpn_connection_activated(NMPolicy *self, NMVpnConnection *vpn)
-{
- NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
- NMIP4Config * ip4_config;
- NMIP6Config * ip6_config;
-
- nm_dns_manager_begin_updates(priv->dns_manager, __func__);
-
- ip4_config = nm_vpn_connection_get_ip4_config(vpn);
- if (ip4_config)
- nm_dns_manager_set_ip_config(priv->dns_manager,
- NM_IP_CONFIG_CAST(ip4_config),
- NM_DNS_IP_CONFIG_TYPE_VPN);
-
- ip6_config = nm_vpn_connection_get_ip6_config(vpn);
- if (ip6_config)
- nm_dns_manager_set_ip_config(priv->dns_manager,
- NM_IP_CONFIG_CAST(ip6_config),
- NM_DNS_IP_CONFIG_TYPE_VPN);
-
- update_routing_and_dns(self, TRUE, NULL);
-
- nm_dns_manager_end_updates(priv->dns_manager, __func__);
-}
-
-static void
-vpn_connection_deactivated(NMPolicy *self, NMVpnConnection *vpn)
+vpn_connection_update_dns(NMPolicy *self, NMVpnConnection *vpn, gboolean remove)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
- NMIP4Config * ip4_config;
- NMIP6Config * ip6_config;
+ int IS_IPv4;
nm_dns_manager_begin_updates(priv->dns_manager, __func__);
- ip4_config = nm_vpn_connection_get_ip4_config(vpn);
- if (ip4_config)
- nm_dns_manager_set_ip_config(priv->dns_manager,
- NM_IP_CONFIG_CAST(ip4_config),
- NM_DNS_IP_CONFIG_TYPE_REMOVED);
+ for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
+ int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
+ const NML3ConfigData *l3cd;
- ip6_config = nm_vpn_connection_get_ip6_config(vpn);
- if (ip6_config)
+ l3cd = nm_vpn_connection_get_l3cd(vpn, addr_family);
nm_dns_manager_set_ip_config(priv->dns_manager,
- NM_IP_CONFIG_CAST(ip6_config),
- NM_DNS_IP_CONFIG_TYPE_REMOVED);
+ addr_family,
+ vpn,
+ l3cd,
+ remove ? NM_DNS_IP_CONFIG_TYPE_REMOVED
+ : NM_DNS_IP_CONFIG_TYPE_VPN,
+ TRUE);
+ }
update_routing_and_dns(self, TRUE, NULL);
@@ -2349,13 +2259,14 @@ vpn_connection_state_changed(NMVpnConnection * vpn,
NMActiveConnectionStateReason reason,
NMPolicy * self)
{
+ /* FIXME: we need to track changes to nm_vpn_connection_get_l3cd(). */
if (new_state == NM_VPN_CONNECTION_STATE_ACTIVATED)
- vpn_connection_activated(self, vpn);
+ vpn_connection_update_dns(self, vpn, FALSE);
else if (new_state >= NM_VPN_CONNECTION_STATE_FAILED) {
/* Only clean up IP/DNS if the connection ever got past IP_CONFIG */
if (old_state >= NM_VPN_CONNECTION_STATE_IP_CONFIG_GET
&& old_state <= NM_VPN_CONNECTION_STATE_ACTIVATED)
- vpn_connection_deactivated(self, vpn);
+ vpn_connection_update_dns(self, vpn, TRUE);
}
}
diff --git a/src/core/nm-proxy-config.c b/src/core/nm-proxy-config.c
deleted file mode 100644
index 49156dfae0..0000000000
--- a/src/core/nm-proxy-config.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2016 Atul Anand <atulhjp@gmail.com>.
- */
-
-#include "src/core/nm-default-daemon.h"
-
-#include "nm-proxy-config.h"
-
-#include <stdlib.h>
-
-#include "libnm-core-intern/nm-core-internal.h"
-
-/*****************************************************************************/
-
-typedef struct {
- NMProxyConfigMethod method;
- gboolean browser_only;
- char * pac_url;
- char * pac_script;
-} NMProxyConfigPrivate;
-
-struct _NMProxyConfig {
- GObject parent;
- NMProxyConfigPrivate _priv;
-};
-
-struct _NMProxyConfigClass {
- GObjectClass parent;
-};
-
-G_DEFINE_TYPE(NMProxyConfig, nm_proxy_config, G_TYPE_OBJECT)
-
-#define NM_PROXY_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMProxyConfig, NM_IS_PROXY_CONFIG)
-
-/*****************************************************************************/
-
-void
-nm_proxy_config_set_method(NMProxyConfig *config, NMProxyConfigMethod method)
-{
- NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- priv->method = method;
-}
-
-NMProxyConfigMethod
-nm_proxy_config_get_method(const NMProxyConfig *config)
-{
- const NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- return priv->method;
-}
-
-void
-nm_proxy_config_merge_setting(NMProxyConfig *config, NMSettingProxy *setting)
-{
- const char * tmp = NULL;
- NMProxyConfigPrivate *priv;
- NMSettingProxyMethod method;
-
- if (!setting)
- return;
-
- g_return_if_fail(NM_IS_SETTING_PROXY(setting));
-
- priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- nm_clear_g_free(&priv->pac_script);
-
- method = nm_setting_proxy_get_method(setting);
- switch (method) {
- case NM_SETTING_PROXY_METHOD_AUTO:
- priv->method = NM_PROXY_CONFIG_METHOD_AUTO;
-
- /* Free DHCP Obtained PAC Url (i.e Option 252)
- * only when libnm overrides it.
- */
- tmp = nm_setting_proxy_get_pac_url(setting);
- if (tmp) {
- g_free(priv->pac_url);
- priv->pac_url = g_strdup(tmp);
- }
-
- tmp = nm_setting_proxy_get_pac_script(setting);
- priv->pac_script = g_strdup(tmp);
-
- break;
- case NM_SETTING_PROXY_METHOD_NONE:
- priv->method = NM_PROXY_CONFIG_METHOD_NONE;
- break;
- }
-
- priv->browser_only = nm_setting_proxy_get_browser_only(setting);
-}
-
-gboolean
-nm_proxy_config_get_browser_only(const NMProxyConfig *config)
-{
- const NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- return priv->browser_only;
-}
-
-void
-nm_proxy_config_set_pac_url(NMProxyConfig *config, const char *url)
-{
- NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- g_free(priv->pac_url);
- priv->pac_url = g_strdup(url);
-}
-
-const char *
-nm_proxy_config_get_pac_url(const NMProxyConfig *config)
-{
- const NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- return priv->pac_url;
-}
-
-void
-nm_proxy_config_set_pac_script(NMProxyConfig *config, const char *script)
-{
- NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- g_free(priv->pac_script);
- priv->pac_script = g_strdup(script);
-}
-
-const char *
-nm_proxy_config_get_pac_script(const NMProxyConfig *config)
-{
- const NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- return priv->pac_script;
-}
-
-/*****************************************************************************/
-
-static void
-nm_proxy_config_init(NMProxyConfig *config)
-{
- NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(config);
-
- priv->method = NM_PROXY_CONFIG_METHOD_NONE;
-}
-
-NMProxyConfig *
-nm_proxy_config_new(void)
-{
- return g_object_new(NM_TYPE_PROXY_CONFIG, NULL);
-}
-
-static void
-finalize(GObject *object)
-{
- NMProxyConfig * self = NM_PROXY_CONFIG(object);
- NMProxyConfigPrivate *priv = NM_PROXY_CONFIG_GET_PRIVATE(self);
-
- g_free(priv->pac_url);
- g_free(priv->pac_script);
-
- G_OBJECT_CLASS(nm_proxy_config_parent_class)->finalize(object);
-}
-
-static void
-nm_proxy_config_class_init(NMProxyConfigClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- object_class->finalize = finalize;
-}
diff --git a/src/core/nm-proxy-config.h b/src/core/nm-proxy-config.h
deleted file mode 100644
index 7b6241f849..0000000000
--- a/src/core/nm-proxy-config.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2016 Atul Anand <atulhjp@gmail.com>.
- */
-
-#ifndef __NETWORKMANAGER_PROXY_CONFIG_H__
-#define __NETWORKMANAGER_PROXY_CONFIG_H__
-
-#include "nm-setting-proxy.h"
-#include "nm-l3-config-data.h"
-
-#define NM_TYPE_PROXY_CONFIG (nm_proxy_config_get_type())
-#define NM_PROXY_CONFIG(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_PROXY_CONFIG, NMProxyConfig))
-#define NM_PROXY_CONFIG_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_PROXY_CONFIG, NMProxyConfigClass))
-#define NM_IS_PROXY_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_PROXY_CONFIG))
-#define NM_IS_PROXY_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_PROXY_CONFIG))
-#define NM_PROXY_CONFIG_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_PROXY_CONFIG, NMProxyConfigClass))
-
-typedef struct _NMProxyConfigClass NMProxyConfigClass;
-
-GType nm_proxy_config_get_type(void);
-
-NMProxyConfig *nm_proxy_config_new(void);
-
-void nm_proxy_config_set_method(NMProxyConfig *config, NMProxyConfigMethod method);
-NMProxyConfigMethod nm_proxy_config_get_method(const NMProxyConfig *config);
-
-void nm_proxy_config_merge_setting(NMProxyConfig *config, NMSettingProxy *setting);
-
-gboolean nm_proxy_config_get_browser_only(const NMProxyConfig *config);
-
-void nm_proxy_config_set_pac_url(NMProxyConfig *config, const char *url);
-const char *nm_proxy_config_get_pac_url(const NMProxyConfig *config);
-
-void nm_proxy_config_set_pac_script(NMProxyConfig *config, const char *script);
-const char *nm_proxy_config_get_pac_script(const NMProxyConfig *config);
-
-#endif /* __NETWORKMANAGER_PROXY_CONFIG_H__ */
diff --git a/src/core/nm-types.h b/src/core/nm-types.h
index 7ad5aee15a..72320fe132 100644
--- a/src/core/nm-types.h
+++ b/src/core/nm-types.h
@@ -25,10 +25,7 @@ typedef struct _NML3Cfg NML3Cfg;
typedef struct _NML3ConfigData NML3ConfigData;
typedef struct _NMDevice NMDevice;
typedef struct _NMDhcpConfig NMDhcpConfig;
-typedef struct _NMProxyConfig NMProxyConfig;
typedef struct _NMIPConfig NMIPConfig;
-typedef struct _NMIP4Config NMIP4Config;
-typedef struct _NMIP6Config NMIP6Config;
typedef struct _NMManager NMManager;
typedef struct _NMNetns NMNetns;
typedef struct _NMPolicy NMPolicy;
diff --git a/src/core/ppp/nm-ppp-manager-call.c b/src/core/ppp/nm-ppp-manager-call.c
index 5e84f59610..8adeb8adbe 100644
--- a/src/core/ppp/nm-ppp-manager-call.c
+++ b/src/core/ppp/nm-ppp-manager-call.c
@@ -94,24 +94,6 @@ again:
return ret;
}
-void
-nm_ppp_manager_set_route_parameters(NMPPPManager *self,
- guint32 ip4_route_table,
- guint32 ip4_route_metric,
- guint32 ip6_route_table,
- guint32 ip6_route_metric)
-{
- const NMPPPOps *ppp_ops = ppp_ops_get();
-
- g_return_if_fail(ppp_ops);
-
- ppp_ops->set_route_parameters(self,
- ip4_route_table,
- ip4_route_metric,
- ip6_route_table,
- ip6_route_metric);
-}
-
gboolean
nm_ppp_manager_start(NMPPPManager *self,
NMActRequest *req,
diff --git a/src/core/ppp/nm-ppp-manager-call.h b/src/core/ppp/nm-ppp-manager-call.h
index c831cf0d61..87d2f93f55 100644
--- a/src/core/ppp/nm-ppp-manager-call.h
+++ b/src/core/ppp/nm-ppp-manager-call.h
@@ -10,12 +10,6 @@
NMPPPManager *nm_ppp_manager_create(const char *iface, GError **error);
-void nm_ppp_manager_set_route_parameters(NMPPPManager *ppp_manager,
- guint32 ip4_route_table,
- guint32 ip4_route_metric,
- guint32 ip6_route_table,
- guint32 ip6_route_metric);
-
gboolean nm_ppp_manager_start(NMPPPManager *self,
NMActRequest *req,
const char * ppp_name,
diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c
index fefc5d613d..25c5217980 100644
--- a/src/core/ppp/nm-ppp-manager.c
+++ b/src/core/ppp/nm-ppp-manager.c
@@ -32,8 +32,7 @@
#include "libnm-platform/nm-platform-utils.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-act-request.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
+#include "nm-l3-config-data.h"
#include "nm-dbus-object.h"
#include "nm-pppd-plugin.h"
@@ -62,8 +61,7 @@ GType nm_ppp_manager_get_type(void);
enum {
STATE_CHANGED,
IFINDEX_SET,
- IP4_CONFIG,
- IP6_CONFIG,
+ NEW_CONFIG,
STATS,
LAST_SIGNAL
@@ -91,11 +89,6 @@ typedef struct {
/* Monitoring */
int monitor_fd;
guint monitor_id;
-
- guint32 ip4_route_table;
- guint32 ip4_route_metric;
- guint32 ip6_route_table;
- guint32 ip6_route_metric;
} NMPPPManagerPrivate;
struct _NMPPPManager {
@@ -131,30 +124,19 @@ static void _ppp_manager_stop_cancel(NMPPPManagerStopHandle *handle);
/*****************************************************************************/
static void
-_ppp_manager_set_route_parameters(NMPPPManager *self,
- guint32 ip4_route_table,
- guint32 ip4_route_metric,
- guint32 ip6_route_table,
- guint32 ip6_route_metric)
+_emit_signal_new_config(NMPPPManager * self,
+ int addr_family,
+ const NML3ConfigData * l3cd,
+ const NMUtilsIPv6IfaceId *iid)
{
- NMPPPManagerPrivate *priv;
+ nm_assert(NM_IS_PPP_MANAGER(self));
+ nm_assert_addr_family(addr_family);
+ nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
+ nm_assert((!!iid) == (addr_family == AF_INET6));
- g_return_if_fail(NM_IS_PPP_MANAGER(self));
+ nm_l3_config_data_seal(l3cd);
- priv = NM_PPP_MANAGER_GET_PRIVATE(self);
- if (priv->ip4_route_table != ip4_route_table || priv->ip4_route_metric != ip4_route_metric
- || priv->ip6_route_table != ip6_route_table || priv->ip6_route_metric != ip6_route_metric) {
- priv->ip4_route_table = ip4_route_table;
- priv->ip4_route_metric = ip4_route_metric;
- priv->ip6_route_table = ip6_route_table;
- priv->ip6_route_metric = ip6_route_metric;
-
- _LOGT("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u",
- priv->ip4_route_table,
- priv->ip4_route_metric,
- priv->ip6_route_table,
- priv->ip6_route_metric);
- }
+ g_signal_emit(self, signals[NEW_CONFIG], 0, addr_family, l3cd, iid);
}
/*****************************************************************************/
@@ -510,12 +492,12 @@ impl_ppp_manager_set_ip4_config(NMDBusObject * obj,
GDBusMethodInvocation * invocation,
GVariant * parameters)
{
- NMPPPManager * self = NM_PPP_MANAGER(obj);
- NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self);
- gs_unref_object NMIP4Config *config = NULL;
- NMPlatformIP4Address address;
- guint32 u32, mtu;
- GVariantIter * iter;
+ NMPPPManager * self = NM_PPP_MANAGER(obj);
+ NMPPPManagerPrivate * priv = NM_PPP_MANAGER_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMPlatformIP4Address address;
+ guint32 u32, mtu;
+ GVariantIter * iter;
gs_unref_variant GVariant *config_dict = NULL;
_LOGI("(IPv4 Config Get) reply received.");
@@ -527,37 +509,40 @@ impl_ppp_manager_set_ip4_config(NMDBusObject * obj,
if (!set_ip_config_common(self, config_dict, &mtu))
goto out;
- config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), priv->ifindex);
+ l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), priv->ifindex);
- if (mtu)
- nm_ip4_config_set_mtu(config, mtu, NM_IP_CONFIG_SOURCE_PPP);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_PPP);
+ nm_l3_config_data_set_mtu(l3cd, mtu);
- memset(&address, 0, sizeof(address));
- address.plen = 32;
+ address = (NMPlatformIP4Address){
+ .plen = 32,
+ };
if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_ADDRESS, "u", &u32))
address.address = u32;
+ if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_PREFIX, "u", &u32))
+ address.plen = u32;
+
if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_GATEWAY, "u", &u32)) {
const NMPlatformIP4Route r = {
.ifindex = priv->ifindex,
.rt_source = NM_IP_CONFIG_SOURCE_PPP,
.gateway = u32,
- .table_coerced = nm_platform_route_table_coerce(priv->ip4_route_table),
- .metric = priv->ip4_route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
- nm_ip4_config_add_route(config, &r, NULL);
+ nm_l3_config_data_add_route_4(l3cd, &r);
address.peer_address = u32;
} else
address.peer_address = address.address;
- if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_PREFIX, "u", &u32))
- address.plen = u32;
-
- if (address.address && address.plen && address.plen <= 32) {
+ if (address.address && address.plen > 0 && address.plen <= 32) {
address.addr_source = NM_IP_CONFIG_SOURCE_PPP;
- nm_ip4_config_add_address(config, &address);
+ nm_l3_config_data_add_address_4(l3cd, &address);
} else {
_LOGE("invalid IPv4 address received!");
goto out;
@@ -565,18 +550,17 @@ impl_ppp_manager_set_ip4_config(NMDBusObject * obj,
if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_DNS, "au", &iter)) {
while (g_variant_iter_next(iter, "u", &u32))
- nm_ip4_config_add_nameserver(config, u32);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET, &u32);
g_variant_iter_free(iter);
}
if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_WINS, "au", &iter)) {
while (g_variant_iter_next(iter, "u", &u32))
- nm_ip4_config_add_wins(config, u32);
+ nm_l3_config_data_add_wins(l3cd, u32);
g_variant_iter_free(iter);
}
- /* Push the IP4 config up to the device */
- g_signal_emit(self, signals[IP4_CONFIG], 0, config);
+ _emit_signal_new_config(self, AF_INET, l3cd, NULL);
out:
g_dbus_method_invocation_return_value(invocation, NULL);
@@ -620,14 +604,14 @@ impl_ppp_manager_set_ip6_config(NMDBusObject * obj,
GDBusMethodInvocation * invocation,
GVariant * parameters)
{
- NMPPPManager * self = NM_PPP_MANAGER(obj);
- NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self);
- gs_unref_object NMIP6Config *config = NULL;
- NMPlatformIP6Address addr;
- struct in6_addr a;
- NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT;
- gboolean has_peer = FALSE;
- gs_unref_variant GVariant *config_dict = NULL;
+ NMPPPManager * self = NM_PPP_MANAGER(obj);
+ NMPPPManagerPrivate * priv = NM_PPP_MANAGER_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMPlatformIP6Address address;
+ struct in6_addr a;
+ NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT;
+ gboolean has_peer = FALSE;
+ gs_unref_variant GVariant *config_dict = NULL;
_LOGI("(IPv6 Config Get) reply received.");
@@ -638,32 +622,34 @@ impl_ppp_manager_set_ip6_config(NMDBusObject * obj,
if (!set_ip_config_common(self, config_dict, NULL))
goto out;
- config = nm_ip6_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), priv->ifindex);
+ l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), priv->ifindex);
- memset(&addr, 0, sizeof(addr));
- addr.plen = 64;
+ address = (NMPlatformIP6Address){
+ .plen = 64,
+ };
if (iid_value_to_ll6_addr(config_dict, NM_PPP_IP6_CONFIG_PEER_IID, &a, NULL)) {
const NMPlatformIP6Route r = {
.ifindex = priv->ifindex,
.rt_source = NM_IP_CONFIG_SOURCE_PPP,
.gateway = a,
- .table_coerced = nm_platform_route_table_coerce(priv->ip6_route_table),
- .metric = priv->ip6_route_metric,
+ .table_any = TRUE,
+ .table_coerced = 0,
+ .metric_any = TRUE,
+ .metric = 0,
};
- nm_ip6_config_add_route(config, &r, NULL);
- addr.peer_address = a;
- has_peer = TRUE;
+ nm_l3_config_data_add_route_6(l3cd, &r);
+ address.peer_address = a;
+ has_peer = TRUE;
}
- if (iid_value_to_ll6_addr(config_dict, NM_PPP_IP6_CONFIG_OUR_IID, &addr.address, &iid)) {
+ if (iid_value_to_ll6_addr(config_dict, NM_PPP_IP6_CONFIG_OUR_IID, &address.address, &iid)) {
if (!has_peer)
- addr.peer_address = addr.address;
- nm_ip6_config_add_address(config, &addr);
+ address.peer_address = address.address;
+ nm_l3_config_data_add_address_6(l3cd, &address);
- /* Push the IPv6 config and interface identifier up to the device */
- g_signal_emit(self, signals[IP6_CONFIG], 0, &iid, config);
+ _emit_signal_new_config(self, AF_INET6, l3cd, &iid);
} else
_LOGE("invalid IPv6 address received!");
@@ -1290,12 +1276,8 @@ nm_ppp_manager_init(NMPPPManager *self)
{
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self);
- priv->ifindex = -1;
- priv->monitor_fd = -1;
- priv->ip4_route_table = RT_TABLE_MAIN;
- priv->ip4_route_metric = 460;
- priv->ip6_route_table = RT_TABLE_MAIN;
- priv->ip6_route_metric = 460;
+ priv->ifindex = -1;
+ priv->monitor_fd = -1;
}
static NMPPPManager *
@@ -1414,18 +1396,7 @@ nm_ppp_manager_class_init(NMPPPManagerClass *manager_class)
G_TYPE_INT,
G_TYPE_STRING);
- signals[IP4_CONFIG] = g_signal_new(NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- signals[IP6_CONFIG] = g_signal_new(NM_PPP_MANAGER_SIGNAL_IP6_CONFIG,
+ signals[NEW_CONFIG] = g_signal_new(NM_PPP_MANAGER_SIGNAL_NEW_CONFIG,
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
0,
@@ -1433,9 +1404,10 @@ nm_ppp_manager_class_init(NMPPPManagerClass *manager_class)
NULL,
NULL,
G_TYPE_NONE,
- 2,
- G_TYPE_POINTER,
- G_TYPE_OBJECT);
+ 3,
+ G_TYPE_INT, /* addr_family */
+ G_TYPE_POINTER, /* (const NML3ConfigData *) */
+ G_TYPE_POINTER); /* (const NMUtilsIPv6IfaceId *) */
signals[STATS] = g_signal_new(NM_PPP_MANAGER_SIGNAL_STATS,
G_OBJECT_CLASS_TYPE(object_class),
@@ -1451,9 +1423,8 @@ nm_ppp_manager_class_init(NMPPPManagerClass *manager_class)
}
const NMPPPOps ppp_ops = {
- .create = _ppp_manager_new,
- .set_route_parameters = _ppp_manager_set_route_parameters,
- .start = _ppp_manager_start,
- .stop = _ppp_manager_stop,
- .stop_cancel = _ppp_manager_stop_cancel,
+ .create = _ppp_manager_new,
+ .start = _ppp_manager_start,
+ .stop = _ppp_manager_stop,
+ .stop_cancel = _ppp_manager_stop_cancel,
};
diff --git a/src/core/ppp/nm-ppp-manager.h b/src/core/ppp/nm-ppp-manager.h
index c41dda2074..9cf465517c 100644
--- a/src/core/ppp/nm-ppp-manager.h
+++ b/src/core/ppp/nm-ppp-manager.h
@@ -11,8 +11,7 @@
#define NM_PPP_MANAGER_SIGNAL_STATE_CHANGED "state-changed"
#define NM_PPP_MANAGER_SIGNAL_IFINDEX_SET "ifindex-set"
-#define NM_PPP_MANAGER_SIGNAL_IP4_CONFIG "ip4-config"
-#define NM_PPP_MANAGER_SIGNAL_IP6_CONFIG "ip6-config"
+#define NM_PPP_MANAGER_SIGNAL_NEW_CONFIG "new-config"
#define NM_PPP_MANAGER_SIGNAL_STATS "stats"
typedef struct _NMPPPManager NMPPPManager;
diff --git a/src/core/ppp/nm-ppp-plugin-api.h b/src/core/ppp/nm-ppp-plugin-api.h
index 647e1c240e..a867b94920 100644
--- a/src/core/ppp/nm-ppp-plugin-api.h
+++ b/src/core/ppp/nm-ppp-plugin-api.h
@@ -11,12 +11,6 @@
typedef const struct {
NMPPPManager *(*create)(const char *iface);
- void (*set_route_parameters)(NMPPPManager *manager,
- guint32 route_table_v4,
- guint32 route_metric_v4,
- guint32 route_table_v6,
- guint32 route_metric_v6);
-
gboolean (*start)(NMPPPManager *manager,
NMActRequest *req,
const char * ppp_name,
diff --git a/src/core/tests/test-ip4-config.c b/src/core/tests/test-ip4-config.c
index 3a095d4ad9..1b38bb2f31 100644
--- a/src/core/tests/test-ip4-config.c
+++ b/src/core/tests/test-ip4-config.c
@@ -7,7 +7,6 @@
#include <arpa/inet.h>
-#include "nm-ip4-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-test-utils-core.h"
diff --git a/src/core/tests/test-ip6-config.c b/src/core/tests/test-ip6-config.c
index ddf4c789c8..5982726f9f 100644
--- a/src/core/tests/test-ip6-config.c
+++ b/src/core/tests/test-ip6-config.c
@@ -8,8 +8,6 @@
#include <arpa/inet.h>
#include <linux/if_addr.h>
-#include "nm-ip6-config.h"
-
#include "libnm-platform/nm-platform.h"
#include "nm-test-utils-core.h"
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
index d06ca46adc..a63428e2fa 100644
--- a/src/core/vpn/nm-vpn-connection.c
+++ b/src/core/vpn/nm-vpn-connection.c
@@ -17,9 +17,6 @@
#include <linux/if.h>
#include <linux/rtnetlink.h>
-#include "nm-proxy-config.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
#include "libnm-platform/nm-platform.h"
#include "nm-active-connection.h"
#include "NetworkManagerUtils.h"
@@ -34,6 +31,7 @@
#include "nm-vpn-plugin-info.h"
#include "nm-vpn-manager.h"
#include "dns/nm-dns-manager.h"
+#include "nm-l3-config-data.h"
typedef enum {
/* Only system secrets */
@@ -100,26 +98,25 @@ typedef struct {
NMNetns *netns;
- GPtrArray *ip4_dev_route_blacklist;
+ NML3Cfg *l3cfg;
GDBusProxy * proxy;
GCancellable * cancellable;
GVariant * connect_hash;
guint connect_timeout;
- NMProxyConfig * proxy_config;
NMPacrunnerConfId *pacrunner_conf_id;
gboolean has_ip4;
- NMIP4Config * ip4_config;
- guint32 ip4_internal_gw;
- guint32 ip4_external_gw;
- gboolean has_ip6;
- NMIP6Config * ip6_config;
-
- /* These config instances are passed on to NMDevice and modified by NMDevice.
- * This pointer is only useful for nm_device_replace_vpn4_config() to clear the
- * previous configuration. Consider these instances to be owned by NMDevice. */
- NMIP4Config *last_device_ip4_config;
- NMIP6Config *last_device_ip6_config;
+
+ union {
+ struct {
+ const NML3ConfigData *l3cd_6;
+ const NML3ConfigData *l3cd_4;
+ };
+ const NML3ConfigData *l3cd_x[2];
+ };
+ guint32 ip4_internal_gw;
+ guint32 ip4_external_gw;
+ gboolean has_ip6;
struct in6_addr *ip6_internal_gw;
struct in6_addr *ip6_external_gw;
@@ -351,6 +348,8 @@ fw_call_cleanup(NMVpnConnection *self)
static void
remove_parent_device_config(NMVpnConnection *connection, NMDevice *device)
{
+ /* FIXME(l3cfg) */
+#if 0
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(connection);
if (priv->last_device_ip4_config) {
@@ -362,6 +361,7 @@ remove_parent_device_config(NMVpnConnection *connection, NMDevice *device)
nm_device_replace_vpn6_config(device, priv->last_device_ip6_config, NULL);
g_clear_object(&priv->last_device_ip6_config);
}
+#endif
}
static void
@@ -514,9 +514,7 @@ _set_vpn_state(NMVpnConnection * self,
_get_applied_connection(self),
parent_dev,
priv->ip_iface,
- priv->proxy_config,
- priv->ip4_config,
- priv->ip6_config,
+ NULL, //XXX
dispatcher_pre_up_done,
self,
&priv->dispatcher_id)) {
@@ -536,21 +534,19 @@ _set_vpn_state(NMVpnConnection * self,
applied,
parent_dev,
priv->ip_iface,
- priv->proxy_config,
- priv->ip4_config,
- priv->ip6_config,
+ NULL, //XXX
NULL,
NULL,
NULL);
- if (priv->proxy_config) {
- nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id);
- priv->pacrunner_conf_id = nm_pacrunner_manager_add(nm_pacrunner_manager_get(),
- priv->proxy_config,
- priv->ip_iface,
- priv->ip4_config,
- priv->ip6_config);
- }
+ //XXX if (priv->proxy_config) {
+ //XXX nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id);
+ //XXX priv->pacrunner_conf_id = nm_pacrunner_manager_add(nm_pacrunner_manager_get(),
+ //XXX priv->proxy_config,
+ //XXX priv->ip_iface,
+ //XXX priv->ip4_config,
+ //XXX priv->ip6_config);
+ //XXX }
break;
case STATE_DEACTIVATING:
applied = _get_applied_connection(self);
@@ -560,18 +556,15 @@ _set_vpn_state(NMVpnConnection * self,
applied,
parent_dev,
priv->ip_iface,
- priv->proxy_config,
- priv->ip4_config,
- priv->ip6_config);
+ NULL //XXX
+ );
} else {
if (!nm_dispatcher_call_vpn(NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
_get_settings_connection(self, FALSE),
applied,
parent_dev,
priv->ip_iface,
- priv->proxy_config,
- priv->ip4_config,
- priv->ip6_config,
+ NULL, //XXX
dispatcher_pre_down_done,
self,
&priv->dispatcher_id)) {
@@ -592,8 +585,6 @@ _set_vpn_state(NMVpnConnection * self,
_get_applied_connection(self),
parent_dev,
priv->ip_iface,
- NULL,
- NULL,
NULL);
} else {
nm_dispatcher_call_vpn(NM_DISPATCHER_ACTION_VPN_DOWN,
@@ -604,8 +595,6 @@ _set_vpn_state(NMVpnConnection * self,
NULL,
NULL,
NULL,
- NULL,
- NULL,
NULL);
}
}
@@ -678,11 +667,12 @@ device_state_changed(NMActiveConnection *active,
*/
}
-static void
-add_ip4_vpn_gateway_route(NMIP4Config *config,
- NMDevice * parent_device,
- in_addr_t vpn_gw,
- NMPlatform * platform)
+//XXX
+_nm_unused static void
+add_ip4_vpn_gateway_route(NML3ConfigData *l3cd,
+ NMDevice * parent_device,
+ in_addr_t vpn_gw,
+ NMPlatform * platform)
{
guint32 parent_gw = 0;
gboolean has_parent_gw = FALSE;
@@ -691,11 +681,11 @@ add_ip4_vpn_gateway_route(NMIP4Config *config,
guint32 route_metric;
nm_auto_nmpobj const NMPObject *route_resolved = NULL;
- g_return_if_fail(NM_IS_IP4_CONFIG(config));
+ nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
g_return_if_fail(NM_IS_DEVICE(parent_device));
g_return_if_fail(vpn_gw != 0);
- ifindex = nm_ip4_config_get_ifindex(config);
+ ifindex = nm_l3_config_data_get_ifindex(l3cd);
nm_assert(ifindex > 0);
nm_assert(ifindex == nm_device_get_ip_ifindex(parent_device));
@@ -737,14 +727,15 @@ add_ip4_vpn_gateway_route(NMIP4Config *config,
route_metric = nm_device_get_route_metric(parent_device, AF_INET);
- memset(&route, 0, sizeof(route));
- route.ifindex = ifindex;
- route.network = vpn_gw;
- route.plen = 32;
- route.gateway = parent_gw;
- route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = route_metric;
- nm_ip4_config_add_route(config, &route, NULL);
+ route = (NMPlatformIP4Route){
+ .ifindex = ifindex,
+ .network = vpn_gw,
+ .plen = 32,
+ .gateway = parent_gw,
+ .rt_source = NM_IP_CONFIG_SOURCE_VPN,
+ .metric = route_metric,
+ };
+ nm_l3_config_data_add_route_4(l3cd, &route);
if (parent_gw) {
/* Ensure there's a route to the parent device's gateway through the
@@ -752,17 +743,19 @@ add_ip4_vpn_gateway_route(NMIP4Config *config,
* routes include a subnet that matches the parent device's subnet,
* the parent device's gateway would get routed through the VPN and fail.
*/
- memset(&route, 0, sizeof(route));
- route.network = parent_gw;
- route.plen = 32;
- route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = route_metric;
- nm_ip4_config_add_route(config, &route, NULL);
+ route = (NMPlatformIP4Route){
+ .network = parent_gw,
+ .plen = 32,
+ .rt_source = NM_IP_CONFIG_SOURCE_VPN,
+ .metric = route_metric,
+ };
+ nm_l3_config_data_add_route_4(l3cd, &route);
}
}
-static void
-add_ip6_vpn_gateway_route(NMIP6Config * config,
+//XXX
+_nm_unused static void
+add_ip6_vpn_gateway_route(NML3ConfigData * l3cd,
NMDevice * parent_device,
const struct in6_addr *vpn_gw,
NMPlatform * platform)
@@ -774,11 +767,11 @@ add_ip6_vpn_gateway_route(NMIP6Config * config,
guint32 route_metric;
nm_auto_nmpobj const NMPObject *route_resolved = NULL;
- g_return_if_fail(NM_IS_IP6_CONFIG(config));
+ nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
g_return_if_fail(NM_IS_DEVICE(parent_device));
g_return_if_fail(vpn_gw != NULL);
- ifindex = nm_ip6_config_get_ifindex(config);
+ ifindex = nm_l3_config_data_get_ifindex(l3cd);
nm_assert(ifindex > 0);
nm_assert(ifindex == nm_device_get_ip_ifindex(parent_device));
@@ -820,15 +813,15 @@ add_ip6_vpn_gateway_route(NMIP6Config * config,
route_metric = nm_device_get_route_metric(parent_device, AF_INET6);
- memset(&route, 0, sizeof(route));
- route.ifindex = ifindex;
- route.network = *vpn_gw;
- route.plen = 128;
- if (parent_gw)
- route.gateway = *parent_gw;
- route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = route_metric;
- nm_ip6_config_add_route(config, &route, NULL);
+ route = (NMPlatformIP6Route){
+ .ifindex = ifindex,
+ .network = *vpn_gw,
+ .plen = 128,
+ .gateway = (parent_gw ? *parent_gw : in6addr_any),
+ .rt_source = NM_IP_CONFIG_SOURCE_VPN,
+ .metric = route_metric,
+ };
+ nm_l3_config_data_add_route_6(l3cd, &route);
/* Ensure there's a route to the parent device's gateway through the
* parent device, since if the VPN claims the default route and the VPN
@@ -836,12 +829,13 @@ add_ip6_vpn_gateway_route(NMIP6Config * config,
* the parent device's gateway would get routed through the VPN and fail.
*/
if (parent_gw && !IN6_IS_ADDR_UNSPECIFIED(parent_gw)) {
- memset(&route, 0, sizeof(route));
- route.network = *parent_gw;
- route.plen = 128;
- route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = route_metric;
- nm_ip6_config_add_route(config, &route, NULL);
+ route = (NMPlatformIP6Route){
+ .network = *parent_gw,
+ .plen = 128,
+ .rt_source = NM_IP_CONFIG_SOURCE_VPN,
+ .metric = route_metric,
+ };
+ nm_l3_config_data_add_route_6(l3cd, &route);
}
}
@@ -988,14 +982,13 @@ plugin_state_changed(NMVpnConnection *self, NMVpnServiceState new_service_state)
static void
print_vpn_config(NMVpnConnection *self)
{
- NMVpnConnectionPrivate * priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
- const NMPlatformIP4Address *address4;
- const NMPlatformIP6Address *address6;
- char * dns_domain = NULL;
- guint32 num, i;
- char b1[NM_UTILS_INET_ADDRSTRLEN];
- char b2[NM_UTILS_INET_ADDRSTRLEN];
- NMDedupMultiIter ipconf_iter;
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
+ const char *const * strv;
+ guint num;
+ guint i;
+ char b1[NM_UTILS_INET_ADDRSTRLEN];
+ char sbuf1[sizeof(_nm_utils_to_string_buffer)];
+ NMDedupMultiIter ipconf_iter;
if (priv->ip4_external_gw) {
_LOGI("Data: VPN Gateway: %s", _nm_utils_inet4_ntop(priv->ip4_external_gw, b1));
@@ -1005,78 +998,57 @@ print_vpn_config(NMVpnConnection *self)
_LOGI("Data: Tunnel Device: %s%s%s", NM_PRINT_FMT_QUOTE_STRING(priv->ip_iface));
- if (priv->ip4_config) {
- const NMPlatformIP4Route *route;
-
- _LOGI("Data: IPv4 configuration:");
+ for (i = 0; i < 2; i++) {
+ const gboolean IS_IPv4 = (i == 0);
+ const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
+ const NML3ConfigData *l3cd = priv->l3cd_x[IS_IPv4];
+ const NMPObject * plobj;
+ const guint8 * p_addrs;
- address4 = nm_ip4_config_get_first_address(priv->ip4_config);
- nm_assert(address4);
+ if (!l3cd) {
+ _LOGI("Data: No IPv%c configuration", nm_utils_addr_family_to_char(addr_family));
+ continue;
+ }
- if (priv->ip4_internal_gw)
- _LOGI("Data: Internal Gateway: %s", _nm_utils_inet4_ntop(priv->ip4_internal_gw, b1));
- _LOGI("Data: Internal Address: %s",
- address4 ? _nm_utils_inet4_ntop(address4->address, b1) : "??");
- _LOGI("Data: Internal Prefix: %d", address4 ? (int) address4->plen : -1);
- _LOGI("Data: Internal Point-to-Point Address: %s",
- _nm_utils_inet4_ntop(address4->peer_address, b1));
+ _LOGI("Data: IPv%c configuration:", nm_utils_addr_family_to_char(addr_family));
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route) {
- _LOGI("Data: Static Route: %s/%d Next Hop: %s",
- _nm_utils_inet4_ntop(route->network, b1),
- route->plen,
- _nm_utils_inet4_ntop(route->gateway, b2));
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ l3cd,
+ &plobj,
+ NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)) {
+ _LOGI("Data: Internal Address: %s",
+ nmp_object_to_string(plobj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof(sbuf1)));
}
- num = nm_ip4_config_get_num_nameservers(priv->ip4_config);
- for (i = 0; i < num; i++) {
- _LOGI("Data: Internal DNS: %s",
- _nm_utils_inet4_ntop(nm_ip4_config_get_nameserver(priv->ip4_config, i), b1));
+ if (IS_IPv4) {
+ if (priv->ip4_internal_gw)
+ _LOGI("Data: Internal Gateway: %s",
+ _nm_utils_inet4_ntop(priv->ip4_internal_gw, b1));
+ } else {
+ if (priv->ip6_internal_gw)
+ _LOGI("Data: Internal Gateway: %s",
+ _nm_utils_inet6_ntop(priv->ip6_internal_gw, b1));
}
- if (nm_ip4_config_get_num_domains(priv->ip4_config) > 0)
- dns_domain = (char *) nm_ip4_config_get_domain(priv->ip4_config, 0);
-
- _LOGI("Data: DNS Domain: '%s'", dns_domain ?: "(none)");
- } else
- _LOGI("Data: No IPv4 configuration");
-
- if (priv->ip6_config) {
- const NMPlatformIP6Route *route;
-
- _LOGI("Data: IPv6 configuration:");
-
- address6 = nm_ip6_config_get_first_address(priv->ip6_config);
- nm_assert(address6);
-
- if (priv->ip6_internal_gw)
- _LOGI("Data: Internal Gateway: %s", _nm_utils_inet6_ntop(priv->ip6_internal_gw, b1));
- _LOGI("Data: Internal Address: %s", _nm_utils_inet6_ntop(&address6->address, b1));
- _LOGI("Data: Internal Prefix: %d", address6->plen);
- _LOGI("Data: Internal Point-to-Point Address: %s",
- _nm_utils_inet6_ntop(&address6->peer_address, b1));
-
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->ip6_config, &route) {
- _LOGI("Data: Static Route: %s/%d Next Hop: %s",
- _nm_utils_inet6_ntop(&route->network, b1),
- route->plen,
- _nm_utils_inet6_ntop(&route->gateway, b2));
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ l3cd,
+ &plobj,
+ NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) {
+ _LOGI("Data: Static Route: %s",
+ nmp_object_to_string(plobj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof(sbuf1)));
}
- num = nm_ip6_config_get_num_nameservers(priv->ip6_config);
- for (i = 0; i < num; i++) {
- _LOGI("Data: Internal DNS: %s",
- _nm_utils_inet6_ntop(nm_ip6_config_get_nameserver(priv->ip6_config, i), b1));
+ p_addrs = nm_l3_config_data_get_nameservers(l3cd, addr_family, &num);
+ for (i = 0; i < num; i++, p_addrs += nm_utils_addr_family_to_size(addr_family)) {
+ _LOGI("Data: Internal DNS: %s", nm_utils_inet_ntop(addr_family, p_addrs, b1));
}
- if (nm_ip6_config_get_num_domains(priv->ip6_config) > 0)
- dns_domain = (char *) nm_ip6_config_get_domain(priv->ip6_config, 0);
-
- _LOGI("Data: DNS Domain: '%s'", dns_domain ?: "(none)");
- } else
- _LOGI("Data: No IPv6 configuration");
+ strv = nm_l3_config_data_get_domains(l3cd, addr_family, &num);
+ for (i = 0; i < num; i++)
+ _LOGI("Data: DNS Domain: '%s'", strv[i]);
+ }
- if (priv->banner && strlen(priv->banner)) {
+ if (!nm_str_is_empty(priv->banner)) {
_LOGI("Data: Login Banner:");
_LOGI("Data: -----------------------------------------");
_LOGI("Data: %s", priv->banner);
@@ -1087,62 +1059,63 @@ print_vpn_config(NMVpnConnection *self)
static void
apply_parent_device_config(NMVpnConnection *self)
{
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
- NMDevice * parent_dev = nm_active_connection_get_device(NM_ACTIVE_CONNECTION(self));
- int ifindex;
- NMIP4Config *vpn4_parent_config = NULL;
- NMIP6Config *vpn6_parent_config = NULL;
+#if 0
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+ NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
+ int ifindex;
+ NMIP4Config *vpn4_parent_config = NULL;
+ NMIP6Config *vpn6_parent_config = NULL;
- ifindex = nm_device_get_ip_ifindex(parent_dev);
- if (ifindex > 0) {
- /* If the VPN didn't return a network interface, it is a route-based
+ ifindex = nm_device_get_ip_ifindex (parent_dev);
+ if (ifindex > 0) {
+ /* If the VPN didn't return a network interface, it is a route-based
* VPN (like kernel IPSec) and all IP addressing and routing should
* be done on the parent interface instead.
*/
- if (priv->ip4_config) {
- vpn4_parent_config = nm_ip4_config_new(nm_netns_get_multi_idx(priv->netns), ifindex);
- if (priv->ip_ifindex <= 0)
- nm_ip4_config_merge(vpn4_parent_config,
- priv->ip4_config,
- NM_IP_CONFIG_MERGE_NO_DNS,
- 0);
- }
- if (priv->ip6_config) {
- vpn6_parent_config = nm_ip6_config_new(nm_netns_get_multi_idx(priv->netns), ifindex);
- if (priv->ip_ifindex <= 0)
- nm_ip6_config_merge(vpn6_parent_config,
- priv->ip6_config,
- NM_IP_CONFIG_MERGE_NO_DNS,
- 0);
- }
- }
-
- /* Add any explicit route to the VPN gateway through the parent device */
- if (vpn4_parent_config && priv->ip4_external_gw) {
- add_ip4_vpn_gateway_route(vpn4_parent_config,
- parent_dev,
- priv->ip4_external_gw,
- nm_netns_get_platform(priv->netns));
- }
- if (vpn6_parent_config && priv->ip6_external_gw) {
- add_ip6_vpn_gateway_route(vpn6_parent_config,
- parent_dev,
- priv->ip6_external_gw,
- nm_netns_get_platform(priv->netns));
- }
-
- nm_device_replace_vpn4_config(parent_dev, priv->last_device_ip4_config, vpn4_parent_config);
- g_clear_object(&priv->last_device_ip4_config);
- priv->last_device_ip4_config = vpn4_parent_config;
-
- nm_device_replace_vpn6_config(parent_dev, priv->last_device_ip6_config, vpn6_parent_config);
- g_clear_object(&priv->last_device_ip6_config);
- priv->last_device_ip6_config = vpn6_parent_config;
+ if (priv->ip4_config) {
+ vpn4_parent_config = nm_ip4_config_new (nm_netns_get_multi_idx (priv->netns),
+ ifindex);
+ if (priv->ip_ifindex <= 0)
+ nm_ip4_config_merge (vpn4_parent_config, priv->ip4_config, NM_IP_CONFIG_MERGE_NO_DNS, 0);
+ }
+ if (priv->ip6_config) {
+ vpn6_parent_config = nm_ip6_config_new (nm_netns_get_multi_idx (priv->netns),
+ ifindex);
+ if (priv->ip_ifindex <= 0)
+ nm_ip6_config_merge (vpn6_parent_config, priv->ip6_config, NM_IP_CONFIG_MERGE_NO_DNS, 0);
+ }
+ }
+
+ /* Add any explicit route to the VPN gateway through the parent device */
+ if ( vpn4_parent_config
+ && priv->ip4_external_gw) {
+ add_ip4_vpn_gateway_route (vpn4_parent_config,
+ parent_dev,
+ priv->ip4_external_gw,
+ nm_netns_get_platform (priv->netns));
+ }
+ if ( vpn6_parent_config
+ && priv->ip6_external_gw) {
+ add_ip6_vpn_gateway_route (vpn6_parent_config,
+ parent_dev,
+ priv->ip6_external_gw,
+ nm_netns_get_platform (priv->netns));
+ }
+
+ nm_device_replace_vpn4_config (parent_dev, priv->last_device_ip4_config, vpn4_parent_config);
+ g_clear_object (&priv->last_device_ip4_config);
+ priv->last_device_ip4_config = vpn4_parent_config;
+
+ nm_device_replace_vpn6_config (parent_dev, priv->last_device_ip6_config, vpn6_parent_config);
+ g_clear_object (&priv->last_device_ip6_config);
+ priv->last_device_ip6_config = vpn6_parent_config;
+#endif
}
static gboolean
nm_vpn_connection_apply_config(NMVpnConnection *self)
{
+#if 0
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
apply_parent_device_config(self);
@@ -1189,16 +1162,15 @@ nm_vpn_connection_apply_config(NMVpnConnection *self)
_LOGI("VPN connection: (IP Config Get) complete");
if (priv->vpn_state < STATE_PRE_UP)
_set_vpn_state(self, STATE_PRE_UP, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
+#endif
return TRUE;
}
static void
_cleanup_failed_config(NMVpnConnection *self)
{
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
-
- nm_dbus_object_clear_and_unexport(&priv->ip4_config);
- nm_dbus_object_clear_and_unexport(&priv->ip6_config);
+ //XXX nm_dbus_object_clear_and_unexport(&priv->ip4_config);
+ //XXX nm_dbus_object_clear_and_unexport(&priv->ip6_config);
_LOGW("VPN connection: did not receive valid IP config information");
_set_vpn_state(self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, FALSE);
@@ -1243,10 +1215,10 @@ nm_vpn_connection_config_maybe_complete(NMVpnConnection *self, gboolean success)
return;
if (success) {
- if ((priv->has_ip4 && !priv->ip4_config) || (priv->has_ip6 && !priv->ip6_config)) {
- /* Need to wait for other config */
- return;
- }
+ //XXX if ((priv->has_ip4 && !priv->ip4_config) || (priv->has_ip6 && !priv->ip6_config)) {
+ //XXX /* Need to wait for other config */
+ //XXX return;
+ //XXX }
}
nm_clear_g_source(&priv->connect_timeout);
@@ -1286,26 +1258,23 @@ ip6_addr_from_variant(GVariant *v, struct in6_addr *addr)
g_return_val_if_fail(v, FALSE);
g_return_val_if_fail(addr, FALSE);
+ nm_assert(g_variant_is_of_type(v, G_VARIANT_TYPE("ay")));
- if (g_variant_is_of_type(v, G_VARIANT_TYPE("ay"))) {
- bytes = g_variant_get_fixed_array(v, &len, sizeof(guint8));
- if (len == sizeof(struct in6_addr) && !IN6_IS_ADDR_UNSPECIFIED(bytes)) {
- memcpy(addr, bytes, len);
- return TRUE;
- }
+ bytes = g_variant_get_fixed_array(v, &len, sizeof(guint8));
+ if (len == sizeof(struct in6_addr) && !IN6_IS_ADDR_UNSPECIFIED(bytes)) {
+ memcpy(addr, bytes, len);
+ return TRUE;
}
return FALSE;
}
static struct in6_addr *
-ip6_addr_dup_from_variant(GVariant *v)
+ip6_addr_from_variant_dup(GVariant *v)
{
- struct in6_addr *addr;
+ struct in6_addr addr;
- addr = g_malloc0(sizeof(*addr));
- if (ip6_addr_from_variant(v, addr))
- return addr;
- g_free(addr);
+ if (ip6_addr_from_variant(v, &addr))
+ return nm_memdup(&addr, sizeof(addr));
return NULL;
}
@@ -1356,19 +1325,15 @@ process_generic_config(NMVpnConnection *self, GVariant *dict)
_notify(self, PROP_BANNER);
}
- /* Proxy Config */
- g_clear_object(&priv->proxy_config);
- priv->proxy_config = nm_proxy_config_new();
+ //XXX if (g_variant_lookup(dict, NM_VPN_PLUGIN_CONFIG_PROXY_PAC, "&s", &str)) {
+ //XXX nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
+ //XXX nm_proxy_config_set_pac_url(priv->proxy_config, str);
+ //XXX } else
+ //XXX nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
- if (g_variant_lookup(dict, NM_VPN_PLUGIN_CONFIG_PROXY_PAC, "&s", &str)) {
- nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
- nm_proxy_config_set_pac_url(priv->proxy_config, str);
- } else
- nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
-
- /* User overrides if any from the NMConnection's Proxy settings */
- nm_proxy_config_merge_setting(priv->proxy_config,
- nm_connection_get_setting_proxy(_get_applied_connection(self)));
+ //XXX /* User overrides if any from the NMConnection's Proxy settings */
+ //XXX nm_proxy_config_merge_setting(priv->proxy_config,
+ //XXX nm_connection_get_setting_proxy(_get_applied_connection(self)));
/* External world-visible address of the VPN server */
priv->ip4_external_gw = 0;
@@ -1377,7 +1342,7 @@ process_generic_config(NMVpnConnection *self, GVariant *dict)
if (g_variant_lookup(dict, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "u", &u32)) {
priv->ip4_external_gw = u32;
} else if (g_variant_lookup(dict, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "@ay", &v)) {
- priv->ip6_external_gw = ip6_addr_dup_from_variant(v);
+ priv->ip6_external_gw = ip6_addr_from_variant_dup(v);
g_variant_unref(v);
if (!priv->ip6_external_gw) {
@@ -1414,12 +1379,12 @@ nm_vpn_connection_config_get(NMVpnConnection *self, GVariant *dict)
priv->has_ip4 = FALSE;
if (g_variant_lookup(dict, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &b))
priv->has_ip4 = b;
- nm_dbus_object_clear_and_unexport(&priv->ip4_config);
+ //XXX nm_dbus_object_clear_and_unexport(&priv->ip4_config);
priv->has_ip6 = FALSE;
if (g_variant_lookup(dict, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &b))
priv->has_ip6 = b;
- nm_dbus_object_clear_and_unexport(&priv->ip6_config);
+ //XXX nm_dbus_object_clear_and_unexport(&priv->ip6_config);
nm_vpn_connection_config_maybe_complete(self, TRUE);
}
@@ -1486,20 +1451,20 @@ _is_device_vrf(NMVpnConnection *self)
static void
nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
{
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
- NMPlatformIP4Address address;
- guint32 u32, route_metric;
- NMSettingIPConfig * s_ip;
- NMSettingConnection * s_con;
- guint32 route_table;
- NMIP4Config * config;
- GVariantIter * iter;
- const char * str;
- GVariant * v;
- gboolean b;
- int ip_ifindex;
- guint32 mss = 0;
- gboolean never_default = FALSE;
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMPlatformIP4Address address;
+ guint32 u32, route_metric;
+ NMSettingIPConfig * s_ip;
+ NMSettingConnection * s_con;
+ guint32 route_table;
+ GVariantIter * iter;
+ const char * str;
+ GVariant * v;
+ gboolean b;
+ int ip_ifindex;
+ guint32 mss = 0;
+ gboolean never_default = FALSE;
g_return_if_fail(dict && g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
@@ -1536,11 +1501,13 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
if (ip_ifindex <= 0)
g_return_if_reached();
- config = nm_ip4_config_new(nm_netns_get_multi_idx(priv->netns), ip_ifindex);
- nm_ip4_config_set_dns_priority(config, NM_DNS_PRIORITY_DEFAULT_VPN);
+ l3cd = nm_l3_config_data_new(nm_netns_get_multi_idx(priv->netns), ip_ifindex);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_VPN);
+ nm_l3_config_data_set_dns_priority(l3cd, AF_INET, NM_DNS_PRIORITY_DEFAULT_VPN);
- memset(&address, 0, sizeof(address));
- address.plen = 24;
+ address = (NMPlatformIP4Address){
+ .plen = 24,
+ };
/* Internal address of the VPN subnet's gateway */
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, "u", &u32))
@@ -1559,23 +1526,22 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
if (address.address && address.plen && address.plen <= 32) {
address.addr_source = NM_IP_CONFIG_SOURCE_VPN;
- nm_ip4_config_add_address(config, &address);
+ nm_l3_config_data_add_address_4(l3cd, &address);
} else {
_LOGW("invalid IP4 config received!");
- g_object_unref(config);
nm_vpn_connection_config_maybe_complete(self, FALSE);
return;
}
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_DNS, "au", &iter)) {
while (g_variant_iter_next(iter, "u", &u32))
- nm_ip4_config_add_nameserver(config, u32);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET, &u32);
g_variant_iter_free(iter);
}
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_NBNS, "au", &iter)) {
while (g_variant_iter_next(iter, "u", &u32))
- nm_ip4_config_add_wins(config, u32);
+ nm_l3_config_data_add_wins(l3cd, u32);
g_variant_iter_free(iter);
}
@@ -1583,11 +1549,11 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
mss = u32;
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN, "&s", &str))
- nm_ip4_config_add_domain(config, str);
+ nm_l3_config_data_add_domain(l3cd, AF_INET, str);
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, "as", &iter)) {
while (g_variant_iter_next(iter, "&s", &str))
- nm_ip4_config_add_domain(config, str);
+ nm_l3_config_data_add_domain(l3cd, AF_INET, str);
g_variant_iter_free(iter);
}
@@ -1599,12 +1565,12 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
if (nm_setting_ip_config_get_ignore_auto_routes(s_ip)) {
/* ignore VPN routes */
} else if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, "b", &b) && b) {
- if (priv->ip4_config) {
- NMDedupMultiIter ipconf_iter;
+ if (priv->l3cd_4) {
const NMPlatformIP4Route *route;
+ NMDedupMultiIter ipconf_iter;
- nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route)
- nm_ip4_config_add_route(config, route, NULL);
+ nm_l3_config_data_iter_ip4_route_for_each (&ipconf_iter, priv->l3cd_4, &route)
+ nm_l3_config_data_add_route_4(l3cd, route);
}
} else if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) {
while (g_variant_iter_next(iter, "@au", &v)) {
@@ -1641,7 +1607,7 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
break;
}
- nm_ip4_config_add_route(config, &route, NULL);
+ nm_l3_config_data_add_route_4(l3cd, &route);
break;
default:
break;
@@ -1655,12 +1621,14 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
never_default = b;
/* Merge in user overrides from the NMConnection's IPv4 setting */
- nm_ip4_config_merge_setting(config,
- s_ip,
- nm_setting_connection_get_mdns(s_con),
- nm_setting_connection_get_llmnr(s_con),
- route_table,
- route_metric);
+ (void) s_con;
+ //XXX
+ //nm_ip4_config_merge_setting (config,
+ // s_ip,
+ // nm_setting_connection_get_mdns (s_con),
+ // nm_setting_connection_get_llmnr (s_con),
+ // route_table,
+ // route_metric);
if (!never_default && !nm_setting_ip_config_get_never_default(s_ip)) {
const NMPlatformIP4Route r = {
@@ -1672,45 +1640,47 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
.mss = mss,
};
- nm_ip4_config_add_route(config, &r, NULL);
+ nm_l3_config_data_add_route_4(l3cd, &r);
}
- nm_clear_pointer(&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
+ nm_l3_config_data_add_dependent_routes(l3cd,
+ AF_INET,
+ route_table,
+ nm_vpn_connection_get_ip4_route_metric(self),
+ _is_device_vrf(self));
- nm_ip4_config_add_dependent_routes(config,
- route_table,
- nm_vpn_connection_get_ip4_route_metric(self),
- _is_device_vrf(self),
- &priv->ip4_dev_route_blacklist);
+ //XXX
+#if 0
+ if (priv->ip4_config) {
+ nm_ip4_config_replace (priv->ip4_config, config, NULL);
+ g_object_unref (config);
+ } else {
+ priv->ip4_config = config;
+ nm_dbus_object_export (NM_DBUS_OBJECT (config));
+ g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP4_CONFIG);
+ }
- if (priv->ip4_config) {
- nm_ip4_config_replace(priv->ip4_config, config, NULL);
- g_object_unref(config);
- } else {
- priv->ip4_config = config;
- nm_dbus_object_export(NM_DBUS_OBJECT(config));
- g_object_notify((GObject *) self, NM_ACTIVE_CONNECTION_IP4_CONFIG);
- }
-
- nm_vpn_connection_config_maybe_complete(self, TRUE);
+ nm_vpn_connection_config_maybe_complete (self, TRUE);
+#endif
}
static void
nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
{
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
- NMPlatformIP6Address address;
- guint32 u32, route_metric;
- NMSettingIPConfig * s_ip;
- guint32 route_table;
- NMIP6Config * config;
- GVariantIter * iter;
- const char * str;
- GVariant * v;
- gboolean b;
- int ip_ifindex;
- guint32 mss = 0;
- gboolean never_default = FALSE;
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMPlatformIP6Address address;
+ guint32 u32;
+ guint32 route_metric;
+ NMSettingIPConfig * s_ip;
+ guint32 route_table;
+ GVariantIter * iter;
+ const char * str;
+ GVariant * v;
+ gboolean b;
+ int ip_ifindex;
+ guint32 mss = 0;
+ gboolean never_default = FALSE;
g_return_if_fail(dict && g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
@@ -1734,16 +1704,18 @@ nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
if (ip_ifindex <= 0)
g_return_if_reached();
- config = nm_ip6_config_new(nm_netns_get_multi_idx(priv->netns), ip_ifindex);
- nm_ip6_config_set_dns_priority(config, NM_DNS_PRIORITY_DEFAULT_VPN);
+ l3cd = nm_l3_config_data_new(nm_netns_get_multi_idx(priv->netns), ip_ifindex);
+ nm_l3_config_data_set_source(l3cd, NM_IP_CONFIG_SOURCE_VPN);
+ nm_l3_config_data_set_dns_priority(l3cd, AF_INET6, NM_DNS_PRIORITY_DEFAULT_VPN);
- memset(&address, 0, sizeof(address));
- address.plen = 128;
+ address = (NMPlatformIP6Address){
+ .plen = 128,
+ };
/* Internal address of the VPN subnet's gateway */
nm_clear_g_free(&priv->ip6_internal_gw);
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, "@ay", &v)) {
- priv->ip6_internal_gw = ip6_addr_dup_from_variant(v);
+ priv->ip6_internal_gw = ip6_addr_from_variant_dup(v);
g_variant_unref(v);
}
@@ -1762,10 +1734,9 @@ nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
if (!IN6_IS_ADDR_UNSPECIFIED(&address.address) && address.plen && address.plen <= 128) {
address.addr_source = NM_IP_CONFIG_SOURCE_VPN;
- nm_ip6_config_add_address(config, &address);
+ nm_l3_config_data_add_address_6(l3cd, &address);
} else {
_LOGW("invalid IP6 config received!");
- g_object_unref(config);
nm_vpn_connection_config_maybe_complete(self, FALSE);
return;
}
@@ -1775,7 +1746,7 @@ nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
struct in6_addr dns;
if (ip6_addr_from_variant(v, &dns))
- nm_ip6_config_add_nameserver(config, &dns);
+ nm_l3_config_data_add_nameserver(l3cd, AF_INET6, &dns);
g_variant_unref(v);
}
g_variant_iter_free(iter);
@@ -1785,11 +1756,11 @@ nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
mss = u32;
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN, "&s", &str))
- nm_ip6_config_add_domain(config, str);
+ nm_l3_config_data_add_domain(l3cd, AF_INET6, str);
if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, "as", &iter)) {
while (g_variant_iter_next(iter, "&s", &str))
- nm_ip6_config_add_domain(config, str);
+ nm_l3_config_data_add_domain(l3cd, AF_INET6, str);
g_variant_iter_free(iter);
}
@@ -1800,33 +1771,41 @@ nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
if (nm_setting_ip_config_get_ignore_auto_routes(s_ip)) {
/* Ignore VPN routes */
} else if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES, "b", &b) && b) {
- if (priv->ip6_config) {
- NMDedupMultiIter ipconf_iter;
- const NMPlatformIP6Route *route;
-
- nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->ip6_config, &route)
- nm_ip6_config_add_route(config, route, NULL);
+ if (priv->l3cd_6) {
+ NMDedupMultiIter ipconf_iter;
+ const NMPObject *route;
+
+ nm_l3_config_data_iter_obj_for_each (&ipconf_iter,
+ priv->l3cd_6,
+ &route,
+ NMP_OBJECT_TYPE_IP6_ROUTE)
+ nm_l3_config_data_add_route(l3cd, AF_INET6, route, NULL);
}
} else if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayu)", &iter)) {
- GVariant *dest, *next_hop;
- guint32 prefix, metric;
+ GVariant *next_hop;
+ GVariant *dest;
+ guint32 prefix;
+ guint32 metric;
while (g_variant_iter_next(iter, "(@ayu@ayu)", &dest, &prefix, &next_hop, &metric)) {
- NMPlatformIP6Route route;
+ _nm_unused gs_unref_variant GVariant *nexT_hop_keep_alive = next_hop;
+ _nm_unused gs_unref_variant GVariant *dest_keep_alive = dest;
+ NMPlatformIP6Route route;
- memset(&route, 0, sizeof(route));
+ if (prefix > 128)
+ continue;
- if (!ip6_addr_from_variant(dest, &route.network))
- goto next;
+ route = (NMPlatformIP6Route){
+ .plen = prefix,
+ .table_coerced = nm_platform_route_table_coerce(route_table),
+ .metric = route_metric,
+ .rt_source = NM_IP_CONFIG_SOURCE_VPN,
+ };
- if (prefix > 128)
- goto next;
+ if (!ip6_addr_from_variant(dest, &route.network))
+ continue;
- route.plen = prefix;
ip6_addr_from_variant(next_hop, &route.gateway);
- route.table_coerced = nm_platform_route_table_coerce(route_table);
- route.metric = route_metric;
- route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
nm_utils_ip6_address_clear_host_address(&route.network, &route.network, route.plen);
@@ -1837,14 +1816,10 @@ nm_vpn_connection_ip6_config_get(NMVpnConnection *self, GVariant *dict)
* server, we want to use the NM created route instead of whatever
* the server provides.
*/
- goto next;
+ continue;
}
- nm_ip6_config_add_route(config, &route, NULL);
-
-next:
- g_variant_unref(dest);
- g_variant_unref(next_hop);
+ nm_l3_config_data_add_route_6(l3cd, &route);
}
g_variant_iter_free(iter);
}
@@ -1853,7 +1828,12 @@ next:
never_default = b;
/* Merge in user overrides from the NMConnection's IPv6 setting */
- nm_ip6_config_merge_setting(config, s_ip, route_table, route_metric);
+ //XXX
+ (void) s_ip;
+ //nm_ip6_config_merge_setting (config,
+ // s_ip,
+ // route_table,
+ // route_metric);
if (!never_default && !nm_setting_ip_config_get_never_default(s_ip)) {
const NMPlatformIP6Route r = {
@@ -1865,19 +1845,26 @@ next:
.mss = mss,
};
- nm_ip6_config_add_route(config, &r, NULL);
+ nm_l3_config_data_add_route_6(l3cd, &r);
}
- nm_ip6_config_add_dependent_routes(config, route_table, route_metric, _is_device_vrf(self));
+ nm_l3_config_data_add_dependent_routes(l3cd,
+ AF_INET6,
+ route_table,
+ route_metric,
+ _is_device_vrf(self));
- if (priv->ip6_config) {
- nm_ip6_config_replace(priv->ip6_config, config, NULL);
- g_object_unref(config);
- } else {
- priv->ip6_config = config;
- nm_dbus_object_export(NM_DBUS_OBJECT(config));
- g_object_notify((GObject *) self, NM_ACTIVE_CONNECTION_IP6_CONFIG);
- }
+ //XXX
+#if 0
+ if (priv->ip6_config) {
+ nm_ip6_config_replace (priv->ip6_config, config, NULL);
+ g_object_unref (config);
+ } else {
+ priv->ip6_config = config;
+ nm_dbus_object_export (NM_DBUS_OBJECT (config));
+ g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP6_CONFIG);
+ }
+#endif
nm_vpn_connection_config_maybe_complete(self, TRUE);
}
@@ -2423,28 +2410,12 @@ nm_vpn_connection_get_banner(NMVpnConnection *self)
return NM_VPN_CONNECTION_GET_PRIVATE(self)->banner;
}
-NMProxyConfig *
-nm_vpn_connection_get_proxy_config(NMVpnConnection *self)
-{
- g_return_val_if_fail(NM_IS_VPN_CONNECTION(self), NULL);
-
- return NM_VPN_CONNECTION_GET_PRIVATE(self)->proxy_config;
-}
-
-NMIP4Config *
-nm_vpn_connection_get_ip4_config(NMVpnConnection *self)
-{
- g_return_val_if_fail(NM_IS_VPN_CONNECTION(self), NULL);
-
- return NM_VPN_CONNECTION_GET_PRIVATE(self)->ip4_config;
-}
-
-NMIP6Config *
-nm_vpn_connection_get_ip6_config(NMVpnConnection *self)
+const NML3ConfigData *
+nm_vpn_connection_get_l3cd(NMVpnConnection *self, int addr_family)
{
g_return_val_if_fail(NM_IS_VPN_CONNECTION(self), NULL);
- return NM_VPN_CONNECTION_GET_PRIVATE(self)->ip6_config;
+ return NM_VPN_CONNECTION_GET_PRIVATE(self)->l3cd_x[NM_IS_IPv4(addr_family)];
}
static int
@@ -2820,8 +2791,6 @@ dispose(GObject *object)
nm_clear_pointer(&priv->connect_hash, g_variant_unref);
- nm_clear_pointer(&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
-
nm_clear_g_source(&priv->connect_timeout);
dispatcher_cleanup(self);
@@ -2830,9 +2799,6 @@ dispose(GObject *object)
nm_clear_g_cancellable(&priv->cancellable);
- g_clear_object(&priv->proxy_config);
- nm_dbus_object_clear_and_unexport(&priv->ip4_config);
- nm_dbus_object_clear_and_unexport(&priv->ip6_config);
g_clear_object(&priv->proxy);
g_clear_object(&priv->plugin_info);
@@ -2859,7 +2825,8 @@ finalize(GObject *object)
g_clear_object(&priv->netns);
}
-static gboolean
+//XXX
+_nm_unused static gboolean
ip_config_valid(VpnState state)
{
return (state == STATE_PRE_UP || state == STATE_ACTIVATED);
@@ -2879,14 +2846,14 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
g_value_set_string(value, priv->banner ?: "");
break;
case PROP_IP4_CONFIG:
- nm_dbus_utils_g_value_set_object_path(value,
- ip_config_valid(priv->vpn_state) ? priv->ip4_config
- : NULL);
+ //XXX nm_dbus_utils_g_value_set_object_path(value,
+ //XXX ip_config_valid(priv->vpn_state) ? priv->ip4_config
+ //XXX : NULL);
break;
case PROP_IP6_CONFIG:
- nm_dbus_utils_g_value_set_object_path(value,
- ip_config_valid(priv->vpn_state) ? priv->ip6_config
- : NULL);
+ //XXX nm_dbus_utils_g_value_set_object_path(value,
+ //XXX ip_config_valid(priv->vpn_state) ? priv->ip6_config
+ //XXX : NULL);
break;
case PROP_MASTER:
parent_dev = nm_active_connection_get_device(NM_ACTIVE_CONNECTION(object));
diff --git a/src/core/vpn/nm-vpn-connection.h b/src/core/vpn/nm-vpn-connection.h
index 0209ea3d60..940a20d7a3 100644
--- a/src/core/vpn/nm-vpn-connection.h
+++ b/src/core/vpn/nm-vpn-connection.h
@@ -54,10 +54,8 @@ void nm_vpn_connection_disconnect(NMVpnConnection * self,
NMActiveConnectionStateReason reason,
gboolean quitting);
-NMProxyConfig *nm_vpn_connection_get_proxy_config(NMVpnConnection *self);
+const NML3ConfigData *nm_vpn_connection_get_l3cd(NMVpnConnection *self, int addr_family);
-NMIP4Config * nm_vpn_connection_get_ip4_config(NMVpnConnection *self);
-NMIP6Config * nm_vpn_connection_get_ip6_config(NMVpnConnection *self);
const char * nm_vpn_connection_get_ip_iface(NMVpnConnection *self, gboolean fallback_device);
int nm_vpn_connection_get_ip_ifindex(NMVpnConnection *self, gboolean fallback_device);
guint32 nm_vpn_connection_get_ip4_internal_gateway(NMVpnConnection *self);
diff --git a/src/libnm-systemd-core/meson.build b/src/libnm-systemd-core/meson.build
index 7ecf31640a..66e7cc82c4 100644
--- a/src/libnm-systemd-core/meson.build
+++ b/src/libnm-systemd-core/meson.build
@@ -18,8 +18,6 @@ libnm_systemd_core = static_library(
'src/libsystemd-network/sd-dhcp-lease.c',
'src/libsystemd-network/sd-dhcp6-client.c',
'src/libsystemd-network/sd-dhcp6-lease.c',
- 'src/libsystemd-network/sd-ipv4acd.c',
- 'src/libsystemd-network/sd-ipv4ll.c',
'src/libsystemd-network/sd-lldp.c',
'src/libsystemd/sd-event/event-util.c',
'src/libsystemd/sd-event/sd-event.c',
diff --git a/src/libnm-systemd-core/nm-sd.h b/src/libnm-systemd-core/nm-sd.h
index f346197440..c52f7cfe77 100644
--- a/src/libnm-systemd-core/nm-sd.h
+++ b/src/libnm-systemd-core/nm-sd.h
@@ -9,7 +9,6 @@
#include "src/systemd/sd-dhcp-client.h"
#include "src/systemd/sd-dhcp6-client.h"
#include "src/systemd/sd-lldp.h"
-#include "src/systemd/sd-ipv4ll.h"
/*****************************************************************************/
diff --git a/tools/run-nm-test.sh b/tools/run-nm-test.sh
index 81b94ec648..355a436600 100755
--- a/tools/run-nm-test.sh
+++ b/tools/run-nm-test.sh
@@ -362,7 +362,6 @@ if [ $HAS_ERRORS -eq 0 ]; then
# valgrind doesn't support setns syscall and spams the logfile.
# hack around it...
case "$TEST_NAME" in
- 'test-acd' | \
'test-address-linux' | \
'test-cleanup-linux' | \
'test-config' | \