core: add NMUtilsShareRules API for handling IP tables rules

Currently, shared rules are tracked by NMActRequest. Add a small
type for tracking the shared rules.
This commit is contained in:
Thomas Haller 2020-10-27 09:37:43 +01:00
parent 0438820805
commit 0c2d5fc972
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 146 additions and 0 deletions

View file

@ -1636,3 +1636,127 @@ nm_utils_ip_routes_to_dbus(int addr_family,
NM_SET_OUT(out_route_data, g_variant_builder_end(&builder_data));
NM_SET_OUT(out_routes, g_variant_builder_end(&builder_legacy));
}
/*****************************************************************************/
typedef struct {
char *table;
char *rule;
} ShareRule;
struct _NMUtilsShareRules {
GArray *rules;
};
static void
_share_rule_clear(gpointer data)
{
ShareRule *rule = data;
g_free(rule->table);
g_free(rule->rule);
}
NMUtilsShareRules *
nm_utils_share_rules_new(void)
{
NMUtilsShareRules *self;
self = g_slice_new(NMUtilsShareRules);
*self = (NMUtilsShareRules){
.rules = g_array_sized_new(FALSE, FALSE, sizeof(ShareRule), 10),
};
g_array_set_clear_func(self->rules, _share_rule_clear);
return self;
}
void
nm_utils_share_rules_free(NMUtilsShareRules *self)
{
if (!self)
return;
g_array_unref(self->rules);
nm_g_slice_free(self);
}
void
nm_utils_share_rules_add_rule_take(NMUtilsShareRules *self, const char *table, char *rule_take)
{
ShareRule *rule;
g_return_if_fail(self);
g_return_if_fail(table);
g_return_if_fail(rule_take);
rule = nm_g_array_append_new(self->rules, ShareRule);
*rule = (ShareRule){
.table = g_strdup(table),
.rule = g_steal_pointer(&rule_take),
};
}
void
nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared)
{
guint i;
g_return_if_fail(self);
if (self->rules->len == 0)
return;
/* depending on whether we share or unshare, we add/remote the rules
* in opposite order. */
if (shared)
i = self->rules->len - 1;
else
i = 0;
for (;;) {
gs_free_error GError *error = NULL;
ShareRule * rule;
gs_free const char ** argv = NULL;
gs_free char * cmd = NULL;
int status;
rule = &g_array_index(self->rules, ShareRule, i);
cmd = g_strdup_printf("%s --table %s %s %s",
IPTABLES_PATH,
rule->table,
shared ? "--insert" : "--delete",
rule->rule);
argv = nm_utils_strsplit_set(cmd, " ");
nm_log_info(LOGD_SHARING, "Executing: %s", cmd);
if (!g_spawn_sync("/",
(char **) argv,
(char **) NM_PTRARRAY_EMPTY(const char *),
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
NULL,
NULL,
NULL,
NULL,
&status,
&error)) {
nm_log_warn(LOGD_SHARING, "Error executing command: %s", error->message);
goto next;
}
if (WEXITSTATUS(status)) {
nm_log_warn(LOGD_SHARING, "** Command returned exit status %d.", WEXITSTATUS(status));
}
next:
if (shared) {
if (i == 0)
break;
i--;
} else {
i++;
if (i >= self->rules->len)
break;
}
}
}

View file

@ -224,4 +224,26 @@ NM_AUTO_DEFINE_FCN(NMDhcpLease *, _nm_auto_unref_dhcplease, nm_dhcp_lease_unref)
/*****************************************************************************/
typedef struct _NMUtilsShareRules NMUtilsShareRules;
NMUtilsShareRules *nm_utils_share_rules_new(void);
void nm_utils_share_rules_free(NMUtilsShareRules *self);
void
nm_utils_share_rules_add_rule_take(NMUtilsShareRules *self, const char *table, char *rule_take);
static inline void
nm_utils_share_rules_add_rule(NMUtilsShareRules *self, const char *table, const char *rule)
{
nm_utils_share_rules_add_rule_take(self, table, g_strdup(rule));
}
#define nm_utils_share_rules_add_rule_v(self, table, ...) \
nm_utils_share_rules_add_rule_take((self), (table), g_strdup_printf(__VA_ARGS__))
void nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared);
/*****************************************************************************/
#endif /* __NETWORKMANAGER_UTILS_H__ */