summaryrefslogtreecommitdiff
path: root/src/types.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.c')
-rw-r--r--src/types.c317
1 files changed, 317 insertions, 0 deletions
diff --git a/src/types.c b/src/types.c
new file mode 100644
index 0000000..b723f15
--- /dev/null
+++ b/src/types.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2021 Canonical, Ltd.
+ * Author: Simon Chopin <simon.chopin@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This module contains functions to deal with the Netplan objects,
+ * notably, accessors and destructors. Note that types specific to parsing
+ * are implemented separately.
+ */
+
+#include <glib.h>
+#include "types.h"
+
+#define FREE_AND_NULLIFY(ptr) { g_free(ptr); ptr = NULL; }
+
+/* Helper function to free a GArray after applying a destructor to its
+ * elements. Note that in the most trivial case (g_free) we should probably
+ * have used a GPtrArray directly... */
+static void
+free_garray_with_destructor(GArray** array, void (destructor)(void *))
+{
+ if (*array) {
+ for (size_t i = 0; i < (*array)->len; ++i) {
+ void* ptr = g_array_index(*array, char*, i);
+ destructor(ptr);
+ }
+ g_array_free(*array, TRUE);
+ *array = NULL;
+ }
+}
+
+/* Helper function to free a GHashTable after applying a simple destructor to its
+ * elements. */
+static void
+free_hashtable_with_destructor(GHashTable** hash, void (destructor)(void *)) {
+ if (*hash) {
+ GHashTableIter iter;
+ gpointer key, value;
+ g_hash_table_iter_init(&iter, *hash);
+ while (g_hash_table_iter_next(&iter, &key, &value))
+ destructor(value);
+ g_hash_table_destroy(*hash);
+ *hash = NULL;
+ }
+}
+
+static void
+free_address_options(void* ptr)
+{
+ NetplanAddressOptions* opts = ptr;
+ g_free(opts->address);
+ g_free(opts->label);
+ g_free(opts->lifetime);
+ g_free(opts);
+}
+
+static void
+free_route(void* ptr)
+{
+ NetplanIPRoute* route = ptr;
+ g_free(route->scope);
+ g_free(route->type);
+ g_free(route->to);
+ g_free(route->from);
+ g_free(route->via);
+ g_free(route);
+}
+
+static void
+free_ip_rules(void* ptr)
+{
+ NetplanIPRule* rule = ptr;
+ g_free(rule->to);
+ g_free(rule->from);
+ g_free(rule);
+}
+
+static void
+free_wireguard_peer(void* ptr)
+{
+ NetplanWireguardPeer* wg = ptr;
+ g_free(wg->endpoint);
+ g_free(wg->preshared_key);
+ g_free(wg->public_key);
+ free_garray_with_destructor(&wg->allowed_ips, g_free);
+ g_free(wg);
+}
+
+static void
+reset_auth_settings(NetplanAuthenticationSettings* auth)
+{
+ FREE_AND_NULLIFY(auth->identity);
+ FREE_AND_NULLIFY(auth->anonymous_identity);
+ FREE_AND_NULLIFY(auth->password);
+ FREE_AND_NULLIFY(auth->ca_certificate);
+ FREE_AND_NULLIFY(auth->client_certificate);
+ FREE_AND_NULLIFY(auth->client_key);
+ FREE_AND_NULLIFY(auth->client_key_password);
+ FREE_AND_NULLIFY(auth->phase2_auth);
+ auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_NONE;
+ auth->eap_method = NETPLAN_AUTH_EAP_NONE;
+}
+
+static void
+reset_ovs_settings(NetplanOVSSettings* settings)
+{
+ settings->mcast_snooping = FALSE;
+ settings->rstp = FALSE;
+
+ free_hashtable_with_destructor(&settings->external_ids, g_free);
+ free_hashtable_with_destructor(&settings->other_config, g_free);
+
+ FREE_AND_NULLIFY(settings->lacp);
+ FREE_AND_NULLIFY(settings->fail_mode);
+
+ free_garray_with_destructor(&settings->protocols, g_free);
+ reset_auth_settings(&settings->ssl);
+
+ free_garray_with_destructor(&settings->controller.addresses, g_free);
+ FREE_AND_NULLIFY(settings->controller.connection_mode);
+}
+
+static void
+reset_dhcp_overrides(NetplanDHCPOverrides* overrides)
+{
+ overrides->use_dns = TRUE;
+ FREE_AND_NULLIFY(overrides->use_domains);
+ overrides->use_ntp = TRUE;
+ overrides->send_hostname = TRUE;
+ overrides->use_hostname = TRUE;
+ overrides->use_mtu = TRUE;
+ overrides->use_routes = TRUE;
+ FREE_AND_NULLIFY(overrides->hostname);
+ overrides->metric = NETPLAN_METRIC_UNSPEC;
+}
+
+/* Reset a backend settings object. The caller needs to specify the actual backend as it is not
+ * contained within the object itself! */
+static void
+reset_backend_settings(NetplanBackendSettings* settings, NetplanBackend backend)
+{
+ switch (backend) {
+ case NETPLAN_BACKEND_NETWORKD:
+ FREE_AND_NULLIFY(settings->networkd.unit);
+ break;
+ case NETPLAN_BACKEND_NM:
+ FREE_AND_NULLIFY(settings->nm.name);
+ FREE_AND_NULLIFY(settings->nm.uuid);
+ FREE_AND_NULLIFY(settings->nm.stable_id);
+ FREE_AND_NULLIFY(settings->nm.device);
+ g_datalist_clear(&settings->nm.passthrough);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Free a heap-allocated NetplanWifiAccessPoint object.
+ * Signature made to match the g_hash_table_foreach function.
+ * @key: ignored
+ * @value: pointer to a heap-allocated NetlpanWifiAccessPoint object
+ * @data: pointer to a NetplanBackend value representing the renderer context in which
+ * to interpret the processed object, especially regarding the backend settings
+ */
+static void
+free_access_point(void* key, void* value, void* data)
+{
+ NetplanWifiAccessPoint* ap = value;
+ g_free(ap->ssid);
+ g_free(ap->bssid);
+ reset_auth_settings(&ap->auth);
+ reset_backend_settings(&ap->backend_settings, *((NetplanBackend *)data));
+ g_free(ap);
+}
+
+/* Reset a given network definition to its initial state, releasing any owned data */
+void
+reset_netdef(NetplanNetDefinition* netdef, NetplanDefType new_type, NetplanBackend new_backend) {
+ /* Needed for some cleanups down the line */
+ NetplanBackend backend = netdef->backend;
+
+ netdef->type = new_type;
+ netdef->backend = new_backend;
+ FREE_AND_NULLIFY(netdef->id);
+ memset(netdef->uuid, 0, sizeof(netdef->uuid));
+
+ netdef->optional = FALSE;
+ netdef->optional_addresses = 0;
+ netdef->critical = FALSE;
+
+ netdef->dhcp4 = FALSE;
+ netdef->dhcp6 = FALSE;
+
+ FREE_AND_NULLIFY(netdef->dhcp_identifier);
+
+ reset_dhcp_overrides(&netdef->dhcp4_overrides);
+ reset_dhcp_overrides(&netdef->dhcp6_overrides);
+ netdef->accept_ra = NETPLAN_RA_MODE_KERNEL;
+
+ free_garray_with_destructor(&netdef->ip4_addresses, g_free);
+ free_garray_with_destructor(&netdef->ip6_addresses, g_free);
+ free_garray_with_destructor(&netdef->address_options, free_address_options);
+
+ netdef->ip6_privacy = FALSE;
+ netdef->ip6_addr_gen_mode = NETPLAN_ADDRGEN_DEFAULT;
+ FREE_AND_NULLIFY(netdef->ip6_addr_gen_token);
+
+ FREE_AND_NULLIFY(netdef->gateway4);
+ FREE_AND_NULLIFY(netdef->gateway6);
+ free_garray_with_destructor(&netdef->ip4_nameservers, g_free);
+ free_garray_with_destructor(&netdef->ip6_nameservers, g_free);
+ free_garray_with_destructor(&netdef->search_domains, g_free);
+ free_garray_with_destructor(&netdef->routes, free_route);
+ free_garray_with_destructor(&netdef->ip_rules, free_ip_rules);
+ free_garray_with_destructor(&netdef->wireguard_peers, free_wireguard_peer);
+
+ netdef->linklocal.ipv4 = FALSE;
+ netdef->linklocal.ipv6 = TRUE;
+
+ FREE_AND_NULLIFY(netdef->bridge);
+ FREE_AND_NULLIFY(netdef->bond);
+
+ FREE_AND_NULLIFY(netdef->peer);
+
+ netdef->vlan_id = G_MAXUINT; /* 0 is a valid ID */
+ netdef->vlan_link = NULL;
+ netdef->has_vlans = FALSE;
+
+ FREE_AND_NULLIFY(netdef->set_mac);
+ netdef->mtubytes = 0;
+ netdef->ipv6_mtubytes = 0;
+
+ FREE_AND_NULLIFY(netdef->set_name);
+ FREE_AND_NULLIFY(netdef->match.driver);
+ FREE_AND_NULLIFY(netdef->match.mac);
+ FREE_AND_NULLIFY(netdef->match.original_name);
+ netdef->has_match = FALSE;
+ netdef->wake_on_lan = FALSE;
+ netdef->wowlan = 0;
+ netdef->emit_lldp = FALSE;
+
+ if (netdef->access_points) {
+ g_hash_table_foreach(netdef->access_points, free_access_point, &backend);
+ g_hash_table_destroy(netdef->access_points);
+ netdef->access_points = NULL;
+ }
+
+ FREE_AND_NULLIFY(netdef->bond_params.mode);
+ FREE_AND_NULLIFY(netdef->bond_params.lacp_rate);
+ FREE_AND_NULLIFY(netdef->bond_params.monitor_interval);
+ FREE_AND_NULLIFY(netdef->bond_params.transmit_hash_policy);
+ FREE_AND_NULLIFY(netdef->bond_params.selection_logic);
+ FREE_AND_NULLIFY(netdef->bond_params.arp_interval);
+ free_garray_with_destructor(&netdef->bond_params.arp_ip_targets, g_free);
+ FREE_AND_NULLIFY(netdef->bond_params.arp_validate);
+ FREE_AND_NULLIFY(netdef->bond_params.arp_all_targets);
+ FREE_AND_NULLIFY(netdef->bond_params.up_delay);
+ FREE_AND_NULLIFY(netdef->bond_params.down_delay);
+ FREE_AND_NULLIFY(netdef->bond_params.fail_over_mac_policy);
+ FREE_AND_NULLIFY(netdef->bond_params.primary_reselect_policy);
+ FREE_AND_NULLIFY(netdef->bond_params.learn_interval);
+ FREE_AND_NULLIFY(netdef->bond_params.primary_slave);
+ memset(&netdef->bond_params, 0, sizeof(netdef->bond_params));
+
+ FREE_AND_NULLIFY(netdef->modem_params.apn);
+ FREE_AND_NULLIFY(netdef->modem_params.device_id);
+ FREE_AND_NULLIFY(netdef->modem_params.network_id);
+ FREE_AND_NULLIFY(netdef->modem_params.number);
+ FREE_AND_NULLIFY(netdef->modem_params.password);
+ FREE_AND_NULLIFY(netdef->modem_params.pin);
+ FREE_AND_NULLIFY(netdef->modem_params.sim_id);
+ FREE_AND_NULLIFY(netdef->modem_params.sim_operator_id);
+ FREE_AND_NULLIFY(netdef->modem_params.username);
+ memset(&netdef->modem_params, 0, sizeof(netdef->modem_params));
+
+ FREE_AND_NULLIFY(netdef->bridge_params.ageing_time);
+ FREE_AND_NULLIFY(netdef->bridge_params.forward_delay);
+ FREE_AND_NULLIFY(netdef->bridge_params.hello_time);
+ FREE_AND_NULLIFY(netdef->bridge_params.max_age);
+ memset(&netdef->bridge_params, 0, sizeof(netdef->bridge_params));
+ netdef->custom_bridging = FALSE;
+
+ FREE_AND_NULLIFY(netdef->tunnel.local_ip);
+ FREE_AND_NULLIFY(netdef->tunnel.remote_ip);
+ FREE_AND_NULLIFY(netdef->tunnel.input_key);
+ FREE_AND_NULLIFY(netdef->tunnel.output_key);
+ FREE_AND_NULLIFY(netdef->tunnel.private_key);
+ memset(&netdef->tunnel, 0, sizeof(netdef->tunnel));
+ netdef->tunnel.mode = NETPLAN_TUNNEL_MODE_UNKNOWN;
+
+ reset_auth_settings(&netdef->auth);
+ netdef->has_auth = FALSE;
+
+ netdef->sriov_link = NULL;
+ netdef->sriov_vlan_filter = FALSE;
+ netdef->sriov_explicit_vf_count = G_MAXUINT; /* 0 is a valid number of VFs */
+
+ reset_ovs_settings(&netdef->ovs_settings);
+ reset_backend_settings(&netdef->backend_settings, backend);
+
+ FREE_AND_NULLIFY(netdef->filename);
+ netdef->tunnel_ttl = 0;
+ FREE_AND_NULLIFY(netdef->activation_mode);
+ netdef->ignore_carrier = FALSE;
+}