dhcp: refactor GType handling for NMDhcpClientFactory

In NetworkManager.conf, we can only configure one "[main].dhcp="
for both address families. Consequently, NMDhcpClientFactory
represents also both address families. However, most plugins
don't support IPv4 and IPv6 together.

Thus, if a plugin does not support an address family, we fallback
to the implementation of the "internal" plugin.

Slightly rework the code how that is done. Instead of having
a "get_type()" and "get_type_per_addr_family()" callback, have
an IPv4 and IPv6 getter.
This commit is contained in:
Thomas Haller 2021-06-17 16:06:15 +02:00
parent 524114add7
commit eb3ef97dd0
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
7 changed files with 31 additions and 46 deletions

View file

@ -217,8 +217,8 @@ gboolean nm_dhcp_client_server_id_is_rejected(NMDhcpClient *self, gconstpointer
*****************************************************************************/
typedef struct {
GType (*get_type)(void);
GType (*get_type_per_addr_family)(int addr_family);
GType (*get_type_4)(void);
GType (*get_type_6)(void);
const char *name;
const char *(*get_path)(void);
bool experimental : 1;

View file

@ -731,9 +731,10 @@ nm_dhcp_dhclient_class_init(NMDhcpDhclientClass *dhclient_class)
}
const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient = {
.name = "dhclient",
.get_type = nm_dhcp_dhclient_get_type,
.get_path = nm_dhcp_dhclient_get_path,
.name = "dhclient",
.get_type_4 = nm_dhcp_dhclient_get_type,
.get_type_6 = nm_dhcp_dhclient_get_type,
.get_path = nm_dhcp_dhclient_get_path,
};
#endif /* WITH_DHCLIENT */

View file

@ -232,9 +232,9 @@ nm_dhcp_dhcpcanon_class_init(NMDhcpDhcpcanonClass *dhcpcanon_class)
}
const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon = {
.name = "dhcpcanon",
.get_type = nm_dhcp_dhcpcanon_get_type,
.get_path = nm_dhcp_dhcpcanon_get_path,
.name = "dhcpcanon",
.get_type_4 = nm_dhcp_dhcpcanon_get_type,
.get_path = nm_dhcp_dhcpcanon_get_path,
};
#endif /* WITH_DHCPCANON */

View file

@ -233,9 +233,9 @@ nm_dhcp_dhcpcd_class_init(NMDhcpDhcpcdClass *dhcpcd_class)
}
const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd = {
.name = "dhcpcd",
.get_type = nm_dhcp_dhcpcd_get_type,
.get_path = nm_dhcp_dhcpcd_get_path,
.name = "dhcpcd",
.get_type_4 = nm_dhcp_dhcpcd_get_type,
.get_path = nm_dhcp_dhcpcd_get_path,
};
#endif /* WITH_DHCPCD */

View file

@ -85,11 +85,10 @@ _client_factory_available(const NMDhcpClientFactory *client_factory)
static GType
_client_factory_get_gtype(const NMDhcpClientFactory *client_factory, int addr_family)
{
GType gtype;
nm_auto_unref_gtypeclass NMDhcpClientClass *klass = NULL;
GType gtype;
GType (*get_type_fcn)(void);
nm_assert(client_factory);
nm_assert_addr_family(addr_family);
/* currently, the chosen DHCP plugin for IPv4 and IPv6 is configured in NetworkManager.conf
* and cannot be reloaded. It would be nice to configure the plugin per address family
@ -111,29 +110,22 @@ _client_factory_get_gtype(const NMDhcpClientFactory *client_factory, int addr_fa
* to those plugins. But we don't intend to do so. The internal plugin is the way forward and
* not extending other plugins. */
if (client_factory->get_type_per_addr_family)
gtype = client_factory->get_type_per_addr_family(addr_family);
if (NM_IS_IPv4(addr_family))
get_type_fcn = client_factory->get_type_4;
else
gtype = client_factory->get_type();
get_type_fcn = client_factory->get_type_6;
if (client_factory == &_nm_dhcp_client_factory_internal) {
/* we are already using the internal plugin. Nothing to do. */
goto out;
if (!get_type_fcn) {
/* If the factory does not support the address family, we always
* fallback to the internal. */
if (NM_IS_IPv4(addr_family))
get_type_fcn = _nm_dhcp_client_factory_internal.get_type_4;
else
get_type_fcn = _nm_dhcp_client_factory_internal.get_type_6;
}
klass = g_type_class_ref(gtype);
gtype = get_type_fcn();
nm_assert(NM_IS_DHCP_CLIENT_CLASS(klass));
if (addr_family == AF_INET6) {
if (!klass->ip6_start)
gtype = _client_factory_get_gtype(&_nm_dhcp_client_factory_internal, addr_family);
} else {
if (!klass->ip4_start)
gtype = _client_factory_get_gtype(&_nm_dhcp_client_factory_internal, addr_family);
}
out:
nm_assert(g_type_is_a(gtype, NM_TYPE_DHCP_CLIENT));
nm_assert(({
nm_auto_unref_gtypeclass NMDhcpClientClass *k = g_type_class_ref(gtype);

View file

@ -1248,6 +1248,6 @@ nm_dhcp_nettools_class_init(NMDhcpNettoolsClass *class)
const NMDhcpClientFactory _nm_dhcp_client_factory_nettools = {
.name = "nettools",
.get_type = nm_dhcp_nettools_get_type,
.get_type_4 = nm_dhcp_nettools_get_type,
.experimental = TRUE,
};

View file

@ -1124,23 +1124,15 @@ nm_dhcp_systemd_class_init(NMDhcpSystemdClass *sdhcp_class)
const NMDhcpClientFactory _nm_dhcp_client_factory_systemd = {
.name = "systemd",
.get_type = nm_dhcp_systemd_get_type,
.get_type_4 = nm_dhcp_systemd_get_type,
.get_type_6 = nm_dhcp_systemd_get_type,
.experimental = TRUE,
};
/*****************************************************************************/
static GType
_get_type_per_addr_family(int addr_family)
{
nm_assert_addr_family(addr_family);
if (addr_family == AF_INET)
return nm_dhcp_nettools_get_type();
return nm_dhcp_systemd_get_type();
}
const NMDhcpClientFactory _nm_dhcp_client_factory_internal = {
.name = "internal",
.get_type_per_addr_family = _get_type_per_addr_family,
.name = "internal",
.get_type_4 = nm_dhcp_nettools_get_type,
.get_type_6 = nm_dhcp_systemd_get_type,
};