Commit 5ba2778b authored by Jussi Laakkonen's avatar Jussi Laakkonen

[connman] Define iptables function with callback in firewall rules. JB#44071

This commit adds a possibility to set a iptables adding callback
function for each firewall rule. The adding callback prototype is the
same as __connman_iptables_append() and __connman_iptables_insert() and
is defined as connman_iptables_manage_cb_t in connman.h.

This is used with general, dynamic and tethering rules. With general
rules the rules are appended to the end. With dynamic and tethering
rules the rules are inserted on top of the managed chain. The logic
behind this is that the general rules can be defined as the base rules
and service specific rules override the general rules.
parent 294c6d93
......@@ -984,6 +984,9 @@ int __connman_iptables_delete(int type,
int __connman_iptables_restore_all();
int __connman_iptables_save_all();
typedef int (*connman_iptables_manage_cb_t)(int type, const char *table_name,
const char *chain, const char *rule_spec);
typedef void (*connman_iptables_iterate_chains_cb_t) (const char *chain_name,
void *user_data);
int __connman_iptables_iterate_chains(int type,
......@@ -1059,11 +1062,13 @@ struct firewall_context;
struct firewall_context *__connman_firewall_create(void);
void __connman_firewall_destroy(struct firewall_context *ctx);
int __connman_firewall_add_rule(struct firewall_context *ctx,
connman_iptables_manage_cb_t cb,
const char *config_file,
const char *table,
const char *chain,
const char *rule_fmt, ...);
int __connman_firewall_add_ipv6_rule(struct firewall_context *ctx,
connman_iptables_manage_cb_t cb,
const char *config_file,
const char *table,
const char *chain,
......
......@@ -64,6 +64,7 @@ struct fw_rule {
char *rule_spec;
char *ifname;
char *config_file;
connman_iptables_manage_cb_t cb;
};
struct firewall_context {
......@@ -258,7 +259,8 @@ static char *format_new_rule(int chain, const char* ifname, const char* rule)
return new_rule;
}
static int insert_managed_rule(int type,
static int insert_managed_rule(connman_iptables_manage_cb_t cb,
int type,
const char *table_name,
const char *chain_name,
const char *ifname,
......@@ -311,8 +313,12 @@ static int insert_managed_rule(int type,
chain = g_strdup_printf("%s%s", CHAIN_PREFIX, chain_name);
out:
err = __connman_iptables_append(type, table_name, chain,
full_rule ? full_rule : rule_spec);
if (cb)
err = cb(type, table_name, chain,
full_rule ? full_rule : rule_spec);
else
err = __connman_iptables_append(type, table_name, chain,
full_rule ? full_rule : rule_spec);
if (err < 0)
DBG("table %s cannot append rule %s", table_name,
......@@ -432,8 +438,9 @@ static int firewall_enable_rule(struct fw_rule *rule)
DBG("%d %s %s %s %s", rule->type, rule->table, rule->chain,
rule->ifname, rule->rule_spec);
err = insert_managed_rule(rule->type, rule->table, rule->chain,
rule->ifname, rule->rule_spec);
err = insert_managed_rule(rule->cb, rule->type, rule->table,
rule->chain, rule->ifname,
rule->rule_spec);
if (err < 0) {
DBG("cannot insert managed rule %d", err);
return err;
......@@ -480,6 +487,7 @@ static int firewall_disable_rule(struct fw_rule *rule)
}
int __connman_firewall_add_rule(struct firewall_context *ctx,
connman_iptables_manage_cb_t cb,
const char *config_file,
const char *table,
const char *chain,
......@@ -500,6 +508,7 @@ int __connman_firewall_add_rule(struct firewall_context *ctx,
rule->id = firewall_rule_id++;
rule->type = AF_INET;
rule->enabled = false;
rule->cb = cb;
if (config_file)
rule->config_file = g_path_get_basename(config_file);
......@@ -514,6 +523,7 @@ int __connman_firewall_add_rule(struct firewall_context *ctx,
}
int __connman_firewall_add_ipv6_rule(struct firewall_context *ctx,
connman_iptables_manage_cb_t cb,
const char *config_file,
const char *table,
const char *chain,
......@@ -534,6 +544,7 @@ int __connman_firewall_add_ipv6_rule(struct firewall_context *ctx,
rule->id = firewall_rule_id++;
rule->type = AF_INET6;
rule->enabled = false;
rule->cb = cb;
if (config_file)
rule->config_file = g_path_get_basename(config_file);
......@@ -860,6 +871,7 @@ static gpointer copy_fw_rule(gconstpointer src, gpointer data)
new->id = firewall_rule_id++;
new->enabled = false;
new->type = old->type;
new->cb = old->cb;
if (old->config_file)
new->config_file = g_strdup(old->config_file);
......@@ -1046,18 +1058,19 @@ static int add_default_tethering_rules(struct firewall_context *ctx,
{
/* Add more in the future if needed */
const char *tethering_rules[] = { "-j ACCEPT", NULL };
connman_iptables_manage_cb_t cb = __connman_iptables_insert;
int id;
int i;
/* Add tethering rules for both IPv4 and IPv6 when using usb */
for (i = 0; tethering_rules[i]; i++) {
id = __connman_firewall_add_rule(ctx, NULL, "filter", "INPUT",
tethering_rules[i]);
id = __connman_firewall_add_rule(ctx, cb, NULL, "filter",
"INPUT", tethering_rules[i]);
if (id < 0)
DBG("cannot add IPv4 rule %s",
tethering_rules[i]);
id = __connman_firewall_add_ipv6_rule(ctx, NULL, "filter",
id = __connman_firewall_add_ipv6_rule(ctx, cb, NULL, "filter",
"INPUT", tethering_rules[i]);
if (id < 0)
DBG("cannot add IPv6 rule %s",
......@@ -1753,6 +1766,7 @@ static int add_dynamic_rules_cb(int type, const char *filename,
const char *group, int chain_id, char** rules)
{
enum connman_service_type service_type;
connman_iptables_manage_cb_t cb = __connman_iptables_insert;
char table[] = "filter";
int count = 0;
int err = 0;
......@@ -1789,14 +1803,14 @@ static int add_dynamic_rules_cb(int type, const char *filename,
case AF_INET:
id = __connman_firewall_add_rule(
dynamic_rules[service_type],
filename, table,
cb, filename, table,
builtin_chains[chain_id],
rules[i]);
break;
case AF_INET6:
id = __connman_firewall_add_ipv6_rule(
dynamic_rules[service_type],
filename, table,
cb, filename, table,
builtin_chains[chain_id],
rules[i]);
break;
......@@ -1824,6 +1838,7 @@ static int add_dynamic_rules_cb(int type, const char *filename,
static int add_general_rules_cb(int type, const char *filename,
const char *group, int chain_id, char** rules)
{
connman_iptables_manage_cb_t cb = __connman_iptables_append;
char table[] = "filter";
int count = 0;
int err = 0;
......@@ -1869,14 +1884,15 @@ static int add_general_rules_cb(int type, const char *filename,
switch (type) {
case AF_INET:
id = __connman_firewall_add_rule(general_firewall->ctx,
filename, table,
cb, filename, table,
builtin_chains[chain_id],
rules[i]);
break;
case AF_INET6:
id = __connman_firewall_add_ipv6_rule(
general_firewall->ctx, filename,
table, builtin_chains[chain_id],
general_firewall->ctx, cb,
filename, table,
builtin_chains[chain_id],
rules[i]);
break;
default:
......@@ -1904,6 +1920,7 @@ static int add_general_rules_cb(int type, const char *filename,
static int add_tethering_rules_cb(int type, const char *filename,
const char *group, int chain_id, char** rules)
{
connman_iptables_manage_cb_t cb = __connman_iptables_insert;
char table[] = "filter";
int count = 0;
int err = 0;
......@@ -1945,14 +1962,14 @@ static int add_tethering_rules_cb(int type, const char *filename,
switch (type) {
case AF_INET:
id = __connman_firewall_add_rule(tethering_firewall,
id = __connman_firewall_add_rule(tethering_firewall, cb,
filename, table,
builtin_chains[chain_id],
rules[i]);
break;
case AF_INET6:
id = __connman_firewall_add_ipv6_rule(
tethering_firewall,
tethering_firewall, cb,
filename, table,
builtin_chains[chain_id],
rules[i]);
......
......@@ -98,7 +98,7 @@ static int enable_nat(struct connman_nat *nat)
nat->prefixlen,
nat->interface);
err = __connman_firewall_add_rule(nat->fw, NULL, "nat",
err = __connman_firewall_add_rule(nat->fw, NULL, NULL, "nat",
"POSTROUTING", cmd);
g_free(cmd);
if (err < 0)
......
......@@ -205,13 +205,13 @@ static int init_firewall(void)
fw = __connman_firewall_create();
err = __connman_firewall_add_rule(fw, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
err = __connman_firewall_add_rule(fw, NULL, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
if (err < 0)
goto err;
err = __connman_firewall_add_rule(fw, NULL, "mangle", "POSTROUTING",
"-j CONNMARK --save-mark");
err = __connman_firewall_add_rule(fw, NULL, NULL, "mangle",
"POSTROUTING","-j CONNMARK --save-mark");
if (err < 0)
goto err;
......@@ -258,13 +258,15 @@ static int init_firewall_session(struct connman_session *session)
switch (session->policy_config->id_type) {
case CONNMAN_SESSION_ID_TYPE_UID:
err = __connman_firewall_add_rule(fw, NULL, "mangle", "OUTPUT",
err = __connman_firewall_add_rule(fw, NULL, NULL, "mangle",
"OUTPUT",
"-m owner --uid-owner %s -j MARK --set-mark %d",
session->policy_config->id,
session->mark);
break;
case CONNMAN_SESSION_ID_TYPE_GID:
err = __connman_firewall_add_rule(fw, NULL, "mangle", "OUTPUT",
err = __connman_firewall_add_rule(fw, NULL, NULL, "mangle",
"OUTPUT",
"-m owner --gid-owner %s -j MARK --set-mark %d",
session->policy_config->id,
session->mark);
......@@ -402,7 +404,7 @@ static void add_nat_rules(struct connman_session *session)
ifname = connman_inet_ifname(index);
addr = __connman_ipconfig_get_local(ipconfig);
id = __connman_firewall_add_rule(session->fw, NULL, "nat",
id = __connman_firewall_add_rule(session->fw, NULL, NULL, "nat",
"POSTROUTING", "-o %s -j SNAT --to-source %s",
ifname, addr);
g_free(ifname);
......
......@@ -638,7 +638,7 @@ static void test_firewall_basic0(void)
ctx = __connman_firewall_create();
g_assert(ctx);
err = __connman_firewall_add_rule(ctx, NULL, "filter", "INPUT",
err = __connman_firewall_add_rule(ctx, NULL, NULL, "filter", "INPUT",
"-m mark --mark 999 -j LOG");
g_assert(err >= 0);
......@@ -669,11 +669,11 @@ static void test_firewall_basic1(void)
ctx = __connman_firewall_create();
g_assert(ctx);
err = __connman_firewall_add_rule(ctx, NULL, "filter", "INPUT",
err = __connman_firewall_add_rule(ctx, NULL, NULL, "filter", "INPUT",
"-m mark --mark 999 -j LOG");
g_assert(err >= 0);
err = __connman_firewall_add_rule(ctx, NULL, "filter", "OUTPUT",
err = __connman_firewall_add_rule(ctx, NULL, NULL, "filter", "OUTPUT",
"-m mark --mark 999 -j LOG");
g_assert(err >= 0);
......@@ -694,12 +694,12 @@ static void test_firewall_basic2(void)
ctx = __connman_firewall_create();
g_assert(ctx);
err = __connman_firewall_add_rule(ctx, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
err = __connman_firewall_add_rule(ctx, NULL, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
g_assert(err >= 0);
err = __connman_firewall_add_rule(ctx, NULL, "mangle", "POSTROUTING",
"-j CONNMARK --save-mark");
err = __connman_firewall_add_rule(ctx, NULL, NULL, "mangle",
"POSTROUTING", "-j CONNMARK --save-mark");
g_assert(err >= 0);
err = __connman_firewall_enable(ctx);
......@@ -719,7 +719,7 @@ static void test_firewall_basic3(void)
ctx = __connman_firewall_create();
g_assert(ctx);
id = __connman_firewall_add_rule(ctx, NULL, "mangle", "INPUT",
id = __connman_firewall_add_rule(ctx, NULL, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
g_assert(id >= 0);
......@@ -1014,8 +1014,8 @@ static void test_firewall6_basic0(void)
ctx = __connman_firewall_create();
g_assert(ctx);
err = __connman_firewall_add_ipv6_rule(ctx, NULL, "filter", "INPUT",
"-m mark --mark 999 -j LOG");
err = __connman_firewall_add_ipv6_rule(ctx, NULL, NULL, "filter",
"INPUT", "-m mark --mark 999 -j LOG");
g_assert(err >= 0);
err = __connman_firewall_enable(ctx);
......@@ -1045,11 +1045,11 @@ static void test_firewall6_basic1(void)
ctx = __connman_firewall_create();
g_assert(ctx);
err = __connman_firewall_add_ipv6_rule(ctx, NULL, "filter", "INPUT",
"-m mark --mark 999 -j LOG");
err = __connman_firewall_add_ipv6_rule(ctx, NULL, NULL, "filter",
"INPUT", "-m mark --mark 999 -j LOG");
g_assert(err >= 0);
err = __connman_firewall_add_rule(ctx, NULL, "filter", "OUTPUT",
err = __connman_firewall_add_rule(ctx, NULL, NULL, "filter", "OUTPUT",
"-m mark --mark 999 -j LOG");
g_assert(err >= 0);
......@@ -1070,12 +1070,12 @@ static void test_firewall6_basic2(void)
ctx = __connman_firewall_create();
g_assert(ctx);
err = __connman_firewall_add_ipv6_rule(ctx, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
err = __connman_firewall_add_ipv6_rule(ctx, NULL, NULL, "mangle",
"INPUT", "-j CONNMARK --restore-mark");
g_assert(err >= 0);
err = __connman_firewall_add_ipv6_rule(ctx, NULL, "mangle", "POSTROUTING",
"-j CONNMARK --save-mark");
err = __connman_firewall_add_ipv6_rule(ctx, NULL, NULL, "mangle",
"POSTROUTING", "-j CONNMARK --save-mark");
g_assert(err >= 0);
err = __connman_firewall_enable(ctx);
......@@ -1095,7 +1095,7 @@ static void test_firewall6_basic3(void)
ctx = __connman_firewall_create();
g_assert(ctx);
id = __connman_firewall_add_rule(ctx, NULL, "mangle", "INPUT",
id = __connman_firewall_add_rule(ctx, NULL, NULL, "mangle", "INPUT",
"-j CONNMARK --restore-mark");
g_assert(id >= 0);
......@@ -1123,25 +1123,25 @@ static void test_firewall_4and6_basic0(void)
g_assert(ctx);
err = __connman_firewall_add_rule(ctx, NULL, "filter", "INPUT",
err = __connman_firewall_add_rule(ctx, NULL, NULL, "filter", "INPUT",
"-p icmp -m icmp "
"--icmp-type 8/0 -j DROP");
g_assert(err >= 0);
err = __connman_firewall_add_rule(ctx, NULL, "filter", "OUTPUT",
err = __connman_firewall_add_rule(ctx, NULL, NULL, "filter", "OUTPUT",
"-p icmp -m icmp "
"--icmp-type 0/0 -j DROP");
g_assert(err >= 0);
err = __connman_firewall_add_ipv6_rule(ctx, NULL, "filter", "INPUT",
"-p icmpv6 -m icmpv6 "
err = __connman_firewall_add_ipv6_rule(ctx, NULL, NULL, "filter",
"INPUT", "-p icmpv6 -m icmpv6 "
"--icmpv6-type 128/0 -j DROP");
g_assert(err >= 0);
err = __connman_firewall_add_ipv6_rule(ctx, NULL, "filter", "OUTPUT",
"-p icmpv6 -m icmpv6 "
err = __connman_firewall_add_ipv6_rule(ctx, NULL, NULL, "filter",
"OUTPUT", "-p icmpv6 -m icmpv6 "
"--icmpv6-type 129/0 -j DROP");
g_assert(err >= 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment