diff --git a/Makefile.am b/Makefile.am index d960462126..1806992bb5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2569,6 +2569,8 @@ src_core_libNetworkManager_la_SOURCES = \ src/core/nm-dhcp-config.h \ src/core/nm-dispatcher.c \ src/core/nm-dispatcher.h \ + src/core/nm-firewall-utils.c \ + src/core/nm-firewall-utils.h \ src/core/nm-firewalld-manager.c \ src/core/nm-firewalld-manager.h \ src/core/nm-proxy-config.c \ diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c index 6a58289c67..7d3e80be4c 100644 --- a/src/core/NetworkManagerUtils.c +++ b/src/core/NetworkManagerUtils.c @@ -15,6 +15,7 @@ #include "libnm-glib-aux/nm-c-list.h" #include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-str-buf.h" #include "libnm-base/nm-net-aux.h" #include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-utils.h" @@ -1637,206 +1638,6 @@ nm_utils_ip_routes_to_dbus(int addr_family, /*****************************************************************************/ -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; - } - } -} - -void -nm_utils_share_rules_add_all_rules(NMUtilsShareRules *self, - const char * ip_iface, - in_addr_t addr, - guint plen) -{ - in_addr_t netmask; - in_addr_t network; - char str_mask[NM_UTILS_INET_ADDRSTRLEN]; - char str_addr[NM_UTILS_INET_ADDRSTRLEN]; - - nm_assert(self); - - netmask = _nm_utils_ip4_prefix_to_netmask(plen); - _nm_utils_inet4_ntop(netmask, str_mask); - - network = addr & netmask; - _nm_utils_inet4_ntop(network, str_addr); - - nm_utils_share_rules_add_rule_v( - self, - "nat", - "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", - str_addr, - str_mask, - str_addr, - str_mask); - nm_utils_share_rules_add_rule_v( - self, - "filter", - "FORWARD --destination %s/%s --out-interface %s --match state --state " - "ESTABLISHED,RELATED --jump ACCEPT", - str_addr, - str_mask, - ip_iface); - nm_utils_share_rules_add_rule_v(self, - "filter", - "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", - str_addr, - str_mask, - ip_iface); - nm_utils_share_rules_add_rule_v(self, - "filter", - "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", - ip_iface, - ip_iface); - nm_utils_share_rules_add_rule_v(self, - "filter", - "FORWARD --out-interface %s --jump REJECT", - ip_iface); - nm_utils_share_rules_add_rule_v(self, - "filter", - "FORWARD --in-interface %s --jump REJECT", - ip_iface); - nm_utils_share_rules_add_rule_v( - self, - "filter", - "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", - ip_iface); - nm_utils_share_rules_add_rule_v( - self, - "filter", - "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", - ip_iface); - nm_utils_share_rules_add_rule_v( - self, - "filter", - "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", - ip_iface); - nm_utils_share_rules_add_rule_v( - self, - "filter", - "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", - ip_iface); -} - -/*****************************************************************************/ - /* Singleton NMPlatform subclass instance and cached class object */ NM_DEFINE_SINGLETON_INSTANCE(NMPlatform); diff --git a/src/core/NetworkManagerUtils.h b/src/core/NetworkManagerUtils.h index a004dbb718..405f90de46 100644 --- a/src/core/NetworkManagerUtils.h +++ b/src/core/NetworkManagerUtils.h @@ -224,33 +224,6 @@ 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_add_all_rules(NMUtilsShareRules *self, - const char * ip_iface, - in_addr_t addr, - guint plen); - -void nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared); - -/*****************************************************************************/ - void nm_platform_setup(NMPlatform *instance); NMPlatform *nm_platform_get(void); diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 1a2fcb371e..0bfc51ca68 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -52,6 +52,7 @@ #include "dnsmasq/nm-dnsmasq-manager.h" #include "nm-dhcp-config.h" #include "nm-rfkill-manager.h" +#include "nm-firewall-utils.h" #include "nm-firewalld-manager.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" @@ -11571,7 +11572,7 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) NMConnection * conn; NMSettingConnection * s_con; gboolean announce_android_metered; - NMUtilsShareRules * share_rules; + NMFirewallConfig * firewall_config; g_return_val_if_fail(config, FALSE); @@ -11596,13 +11597,9 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) req = nm_device_get_act_request(self); g_return_val_if_fail(req, FALSE); - share_rules = nm_utils_share_rules_new(); + firewall_config = nm_firewall_config_new(ip_iface, ip4_addr->address, ip4_addr->plen); - nm_utils_share_rules_add_all_rules(share_rules, ip_iface, ip4_addr->address, ip4_addr->plen); - - nm_utils_share_rules_apply(share_rules, TRUE); - - nm_act_request_set_shared(req, share_rules); + nm_act_request_set_shared(req, firewall_config); conn = nm_act_request_get_applied_connection(req); s_con = nm_connection_get_setting_connection(conn); diff --git a/src/core/meson.build b/src/core/meson.build index da85b06dbc..ba7dad998b 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -163,6 +163,7 @@ libNetworkManager = static_library( 'nm-dcb.c', 'nm-dhcp-config.c', 'nm-dispatcher.c', + 'nm-firewall-utils.c', 'nm-firewalld-manager.c', 'nm-hostname-manager.c', 'nm-keep-alive.c', diff --git a/src/core/nm-act-request.c b/src/core/nm-act-request.c index cb4b0260a5..d0a2e0c783 100644 --- a/src/core/nm-act-request.c +++ b/src/core/nm-act-request.c @@ -13,17 +13,19 @@ #include #include "c-list/src/c-list.h" - -#include "nm-setting-wireless-security.h" -#include "nm-setting-8021x.h" -#include "devices/nm-device.h" -#include "nm-active-connection.h" -#include "settings/nm-settings-connection.h" #include "libnm-core-aux-intern/nm-auth-subject.h" +#include "nm-setting-8021x.h" +#include "nm-setting-wireless-security.h" + +#include "devices/nm-device.h" +#include "nm-active-connection.h" +#include "nm-firewall-utils.h" +#include "settings/nm-settings-connection.h" + typedef struct { - CList call_ids_lst_head; - NMUtilsShareRules *share_rules; + CList call_ids_lst_head; + NMFirewallConfig *firewall_config; } NMActRequestPrivate; struct _NMActRequest { @@ -248,31 +250,31 @@ nm_act_request_clear_secrets(NMActRequest *self) /*****************************************************************************/ -NMUtilsShareRules * +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)->share_rules; + return NM_ACT_REQUEST_GET_PRIVATE(req)->firewall_config; } void -nm_act_request_set_shared(NMActRequest *req, NMUtilsShareRules *rules) +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->share_rules == rules) + if (priv->firewall_config == rules) return; - if (priv->share_rules) { - nm_utils_share_rules_apply(priv->share_rules, FALSE); - priv->share_rules = NULL; + if (priv->firewall_config) { + nm_firewall_config_apply(priv->firewall_config, FALSE); + priv->firewall_config = NULL; } if (rules) { - priv->share_rules = rules; - nm_utils_share_rules_apply(priv->share_rules, TRUE); + priv->firewall_config = rules; + nm_firewall_config_apply(priv->firewall_config, TRUE); } } @@ -506,9 +508,9 @@ 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->share_rules) { - nm_utils_share_rules_apply(priv->share_rules, FALSE); - nm_clear_pointer(&priv->share_rules, nm_utils_share_rules_free); + 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 2a568430ac..9c702d31eb 100644 --- a/src/core/nm-act-request.h +++ b/src/core/nm-act-request.h @@ -38,11 +38,11 @@ NMConnection *nm_act_request_get_applied_connection(NMActRequest *req); /*****************************************************************************/ -struct _NMUtilsShareRules; +struct _NMFirewallConfig; -struct _NMUtilsShareRules *nm_act_request_get_shared(NMActRequest *req); +struct _NMFirewallConfig *nm_act_request_get_shared(NMActRequest *req); -void nm_act_request_set_shared(NMActRequest *req, struct _NMUtilsShareRules *rules); +void nm_act_request_set_shared(NMActRequest *req, struct _NMFirewallConfig *rules); /*****************************************************************************/ diff --git a/src/core/nm-firewall-utils.c b/src/core/nm-firewall-utils.c new file mode 100644 index 0000000000..dc17e2c040 --- /dev/null +++ b/src/core/nm-firewall-utils.c @@ -0,0 +1,369 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2004 - 2016 Red Hat, Inc. + * Copyright (C) 2005 - 2008 Novell, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include "nm-firewall-utils.h" + +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-platform/nm-platform.h" + +/*****************************************************************************/ + +#define _SHARE_IPTABLES_SUBNET_TO_STR_LEN (INET_ADDRSTRLEN + 1 + 2 + 1) + +static const char * +_share_iptables_subnet_to_str(char buf[static _SHARE_IPTABLES_SUBNET_TO_STR_LEN], + in_addr_t addr, + guint8 plen) +{ + char buf_addr[INET_ADDRSTRLEN]; + in_addr_t netmask; + int l; + + netmask = _nm_utils_ip4_prefix_to_netmask(plen); + + l = g_snprintf(buf, + _SHARE_IPTABLES_SUBNET_TO_STR_LEN, + "%s/%u", + _nm_utils_inet4_ntop(addr & netmask, buf_addr), + plen); + nm_assert(l < _SHARE_IPTABLES_SUBNET_TO_STR_LEN); + return buf; +} + +static char * +_share_iptables_get_name(gboolean is_comment, const char *prefix, const char *ip_iface) +{ + NMStrBuf strbuf = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_40, FALSE); + gsize ip_iface_len; + + nm_assert(prefix); + nm_assert(ip_iface); + + /* This function is used to generate iptables chain names and comments. + * Chain names must be shorter than 29 chars. Comments don't have this + * limitation. + * + * Below we sanitize the ip_iface. If it's all benign, we use + * - either "-$IP_IFACE" (at most 16 chars) + * - otherwise, we base64 encode the name as "$(base64 $IP_IFACE)", at + * most 20 chars. + * + * Since for benign names we already add a '-', prefix probably should not + * contain a '-'. The '-' is necessary to distinguish between base64 encoding + * an plain name. + * + * That means, for chain names the prefix must be at most 8 chars long. */ + nm_assert(is_comment || (strlen(prefix) <= 8)); + + nm_str_buf_append(&strbuf, prefix); + + ip_iface_len = strlen(ip_iface); + G_STATIC_ASSERT_EXPR(NMP_IFNAMSIZ == 16); + if (ip_iface_len >= NMP_IFNAMSIZ) { + nm_assert_not_reached(); + ip_iface_len = NMP_IFNAMSIZ - 1; + } + + if (NM_STRCHAR_ALL(ip_iface, + ch, + (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') || NM_IN_SET(ch, '.', '_', '-', '+'))) { + nm_str_buf_append_c(&strbuf, '-'); + nm_str_buf_append(&strbuf, ip_iface); + } else { + gs_free char *s = NULL; + + s = g_base64_encode((const guchar *) ip_iface, ip_iface_len); + nm_str_buf_append(&strbuf, s); + } + + return nm_str_buf_finalize(&strbuf, NULL); +} + +static gboolean +_share_iptables_call_v(const char *const *argv) +{ + gs_free_error GError *error = NULL; + gs_free char * argv_str = NULL; + int status; + + nm_log_dbg(LOGD_SHARING, "iptables: %s", (argv_str = g_strjoinv(" ", (char **) argv))); + + 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, + "iptables: error executing command %s: %s", + argv[0], + error->message); + return FALSE; + } + + if (!g_spawn_check_exit_status(status, &error)) { + nm_log_warn(LOGD_SHARING, "iptables: command %s failed: %s", argv[0], error->message); + return FALSE; + } + + return TRUE; +} + +#define _share_iptables_call(...) _share_iptables_call_v(NM_MAKE_STRV(__VA_ARGS__)) + +static gboolean +_share_iptables_chain_op(const char *table, const char *chain, const char *op) +{ + return _share_iptables_call("" IPTABLES_PATH "", "--table", table, op, chain); +} + +static gboolean +_share_iptables_chain_delete(const char *table, const char *chain) +{ + _share_iptables_chain_op(table, chain, "--flush"); + return _share_iptables_chain_op(table, chain, "--delete-chain"); +} + +static gboolean +_share_iptables_chain_add(const char *table, const char *chain) +{ + if (_share_iptables_chain_op(table, chain, "--new-chain")) + return TRUE; + + _share_iptables_chain_delete(table, chain); + return _share_iptables_chain_op(table, chain, "--new-chain"); +} + +static void +_share_iptables_set_masquerade(gboolean add, const char *ip_iface, in_addr_t addr, guint8 plen) +{ + char str_subnet[_SHARE_IPTABLES_SUBNET_TO_STR_LEN]; + gs_free char *comment_name = NULL; + + comment_name = _share_iptables_get_name(TRUE, "nm-shared", ip_iface); + + _share_iptables_subnet_to_str(str_subnet, addr, plen); + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "nat", + add ? "--insert" : "--delete", + "POSTROUTING", + "--source", + str_subnet, + "!", + "--destination", + str_subnet, + "--jump", + "MASQUERADE", + "-m", + "comment", + "--comment", + comment_name); +} + +static void +_share_iptables_set_shared_chains_add(const char *chain_input, + const char *chain_forward, + const char *ip_iface, + in_addr_t addr, + guint plen) +{ + const char *const input_params[][2] = { + { + "tcp", + "67", + }, + { + "udp", + "67", + }, + { + "tcp", + "53", + }, + { + "udp", + "53", + }, + }; + char str_subnet[_SHARE_IPTABLES_SUBNET_TO_STR_LEN]; + int i; + + _share_iptables_subnet_to_str(str_subnet, addr, plen); + + _share_iptables_chain_add("filter", chain_input); + + for (i = 0; i < (int) G_N_ELEMENTS(input_params); i++) { + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + "--append", + chain_input, + "--protocol", + input_params[i][0], + "--destination-port", + input_params[i][1], + "--jump", + "ACCEPT"); + } + + _share_iptables_chain_add("filter", chain_forward); + + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + "--append", + chain_forward, + "--destination", + str_subnet, + "--out-interface", + ip_iface, + "--match", + "state", + "--state", + "ESTABLISHED,RELATED", + "--jump", + "ACCEPT"); + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + "--append", + chain_forward, + "--source", + str_subnet, + "--in-interface", + ip_iface, + "--jump", + "ACCEPT"); + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + "--append", + chain_forward, + "--in-interface", + ip_iface, + "--out-interface", + ip_iface, + "--jump", + "ACCEPT"); + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + "--append", + chain_forward, + "--out-interface", + ip_iface, + "--jump", + "REJECT"); + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + "--append", + chain_forward, + "--in-interface", + ip_iface, + "--jump", + "REJECT"); +} + +static void +_share_iptables_set_shared_chains_delete(const char *chain_input, const char *chain_forward) +{ + _share_iptables_chain_delete("filter", chain_input); + _share_iptables_chain_delete("filter", chain_forward); +} + +_nm_unused static void +_share_iptables_set_shared(gboolean add, const char *ip_iface, in_addr_t addr, guint plen) +{ + gs_free char *comment_name = NULL; + gs_free char *chain_input = NULL; + gs_free char *chain_forward = NULL; + + comment_name = _share_iptables_get_name(TRUE, "nm-shared", ip_iface); + chain_input = _share_iptables_get_name(FALSE, "nm-sh-in", ip_iface); + chain_forward = _share_iptables_get_name(FALSE, "nm-sh-fw", ip_iface); + + if (add) + _share_iptables_set_shared_chains_add(chain_input, chain_forward, ip_iface, addr, plen); + + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + add ? "--insert" : "--delete", + "INPUT", + "--in-interface", + ip_iface, + "--jump", + chain_input, + "-m", + "comment", + "--comment", + comment_name); + + _share_iptables_call("" IPTABLES_PATH "", + "--table", + "filter", + add ? "--insert" : "--delete", + "FORWARD", + "--jump", + chain_forward, + "-m", + "comment", + "--comment", + comment_name); + + if (!add) + _share_iptables_set_shared_chains_delete(chain_input, chain_forward); +} + +struct _NMFirewallConfig { + char * ip_iface; + in_addr_t addr; + guint8 plen; +}; + +NMFirewallConfig * +nm_firewall_config_new(const char *ip_iface, in_addr_t addr, guint8 plen) +{ + NMFirewallConfig *self; + + nm_assert(ip_iface); + nm_assert(addr != 0u); + nm_assert(plen <= 32); + + self = g_slice_new(NMFirewallConfig); + *self = (NMFirewallConfig){ + .ip_iface = g_strdup(ip_iface), + .addr = addr, + .plen = plen, + }; + return self; +} + +void +nm_firewall_config_free(NMFirewallConfig *self) +{ + if (!self) + return; + + g_free(self->ip_iface); + nm_g_slice_free(self); +} + +void +nm_firewall_config_apply(NMFirewallConfig *self, gboolean shared) +{ + _share_iptables_set_masquerade(shared, self->ip_iface, self->addr, self->plen); + _share_iptables_set_shared(shared, self->ip_iface, self->addr, self->plen); +} diff --git a/src/core/nm-firewall-utils.h b/src/core/nm-firewall-utils.h new file mode 100644 index 0000000000..5ba1721c2e --- /dev/null +++ b/src/core/nm-firewall-utils.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2004 - 2016 Red Hat, Inc. + * Copyright (C) 2005 - 2008 Novell, Inc. + */ + +#ifndef __NM_FIREWALL_UTILS_H__ +#define __NM_FIREWALL_UTILS_H__ + +typedef struct _NMFirewallConfig NMFirewallConfig; + +NMFirewallConfig *nm_firewall_config_new(const char *ip_iface, in_addr_t addr, guint8 plen); + +void nm_firewall_config_free(NMFirewallConfig *self); + +void nm_firewall_config_apply(NMFirewallConfig *self, gboolean shared); + +#endif /* __NM_FIREWALL_UTILS_H__ */