From: Mateusz Majewski Date: Thu, 14 Jan 2021 14:08:38 +0000 (+0100) Subject: Implement mark matching X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ecc61b2533e4664cacbde390dbeb336f2ff18f79;p=platform%2Fcore%2Fconnectivity%2Fstc-iptables.git Implement mark matching Change-Id: Ib947ef47cc684c1a7e9e0aaa985ae0ed7400bf26 --- diff --git a/src/helper/helper-ip6tables.c b/src/helper/helper-ip6tables.c index edd06bb..8b70dc6 100755 --- a/src/helper/helper-ip6tables.c +++ b/src/helper/helper-ip6tables.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #define IP6T_ALIGN XT_ALIGN #define IP6TC_TABLE "filter" +#define IP6TC_MARK "mark" #define IP6TC_TCP "tcp" #define IP6TC_UDP "udp" #define IP6TC_CGROUP "cgroup" @@ -58,6 +60,7 @@ typedef struct ip6t_entry_match ip6t_entry_match_t; typedef struct ip6t_entry_target ip6t_entry_target_t; /* matches */ +typedef struct xt_mark_mtinfo1 ip6t_mark_info_t; typedef struct xt_tcp ip6t_tcp_info_t; typedef struct xt_udp ip6t_udp_info_t; typedef struct xt_cgroup_info_v0 ip6t_cgroup_info_t; @@ -70,6 +73,7 @@ typedef struct xt_nflog_info ip6t_nflog_info_t; typedef struct xt_NFQ_info_v3 ip6t_nfqueue_info_t; #define SIZE_ENTRY IP6T_ALIGN(sizeof(ip6t_entry_t)) +#define SIZE_MARK_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_mark_info_t)) #define SIZE_TCP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_tcp_info_t)) #define SIZE_UDP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_udp_info_t)) #define SIZE_CGROUP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_cgroup_info_t)) @@ -79,9 +83,9 @@ typedef struct xt_NFQ_info_v3 ip6t_nfqueue_info_t; #define SIZE_TARGET_LOG IP6T_ALIGN(sizeof(ip6t_log_info_t)) #define SIZE_TARGET_NFLOG IP6T_ALIGN(sizeof(ip6t_nflog_info_t)) #define SIZE_TARGET_NFQUEUE IP6T_ALIGN(sizeof(ip6t_nfqueue_info_t)) -#define SIZE_TOTAL SIZE_ENTRY + SIZE_TCP_MATCH + SIZE_UDP_MATCH + SIZE_CGROUP_MATCH \ - + SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH + SIZE_TARGET \ - + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG + SIZE_TARGET_NFQUEUE +#define SIZE_TOTAL SIZE_ENTRY + SIZE_MARK_MATCH + SIZE_TCP_MATCH + SIZE_UDP_MATCH \ + + SIZE_CGROUP_MATCH + SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH \ + + SIZE_TARGET + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG + SIZE_TARGET_NFQUEUE static unsigned int __add_match(const char *name, ip6t_entry_match_t *start, int revision, size_t size, void *data) @@ -148,6 +152,18 @@ static void __add_iprange(unsigned char *entry, unsigned int *size_match, ip6tab e->next_offset += SIZE_IPRANGE_MATCH; } +static unsigned int __add_mark_match(uint32_t mask, uint32_t compare, ip6t_entry_match_t *start) +{ + ip6t_mark_info_t mark; + memset(&mark, 0, sizeof(ip6t_mark_info_t)); + + mark.mask = mask; + mark.mark = compare; + + /* match_mark => "-m mark" */ + return __add_match(IP6TC_MARK, start, 1, sizeof(ip6t_mark_info_t), &mark); +} + static unsigned int __add_port_match(ip6tables_protocol_type_e prot_type, ip6tables_port_type_e sport_type, unsigned short sport1, unsigned short sport2, ip6tables_port_type_e dport_type, unsigned short dport1, unsigned short dport2, @@ -409,6 +425,14 @@ static int __create_entry_data(unsigned char *entry, unsigned char *mask, rule->d_ip_type == IP6TABLES_IP_RANGE) __add_iprange(entry, &size_match, rule); + /* -m mark */ + if (rule->mark_flag_mask > 0) { + size_match += __add_mark_match(rule->mark_flag_mask, rule->mark_flag_compare, + (ip6t_entry_match_t *) (e->elems + size_match)); + e->target_offset += SIZE_MARK_MATCH; + e->next_offset += SIZE_MARK_MATCH; + } + /* -p tcp */ e->ipv6.flags |= IP6T_F_PROTO; diff --git a/src/helper/helper-ip6tables.h b/src/helper/helper-ip6tables.h index b6177bd..760b265 100755 --- a/src/helper/helper-ip6tables.h +++ b/src/helper/helper-ip6tables.h @@ -81,6 +81,8 @@ typedef struct { ip6tables_protocol_type_e protocol; unsigned char tcp_flag_mask; unsigned char tcp_flag_compare; + uint32_t mark_flag_mask; + uint32_t mark_flag_compare; struct in6_addr s_ip1; struct in6_addr s_ip2; struct in6_addr d_ip1; diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c index e0318c8..cbdf7c9 100755 --- a/src/helper/helper-iptables.c +++ b/src/helper/helper-iptables.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #define IPT_ALIGN XT_ALIGN #define IPTC_TABLE "filter" +#define IPTC_MARK "mark" #define IPTC_TCP "tcp" #define IPTC_UDP "udp" #define IPTC_CGROUP "cgroup" @@ -58,6 +60,7 @@ typedef struct ipt_entry_match ipt_entry_match_t; typedef struct ipt_entry_target ipt_entry_target_t; /* matches */ +typedef struct xt_mark_mtinfo1 ipt_mark_info_t; typedef struct xt_tcp ipt_tcp_info_t; typedef struct xt_udp ipt_udp_info_t; typedef struct xt_cgroup_info_v0 ipt_cgroup_info_t; @@ -70,6 +73,7 @@ typedef struct xt_nflog_info ipt_nflog_info_t; typedef struct xt_NFQ_info_v3 ipt_nfqueue_info_t; #define SIZE_ENTRY IPT_ALIGN(sizeof(ipt_entry_t)) +#define SIZE_MARK_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_mark_info_t)) #define SIZE_TCP_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_tcp_info_t)) #define SIZE_UDP_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_udp_info_t)) #define SIZE_CGROUP_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_cgroup_info_t)) @@ -79,9 +83,9 @@ typedef struct xt_NFQ_info_v3 ipt_nfqueue_info_t; #define SIZE_TARGET_LOG IPT_ALIGN(sizeof(ipt_log_info_t)) #define SIZE_TARGET_NFLOG IPT_ALIGN(sizeof(ipt_nflog_info_t)) #define SIZE_TARGET_NFQUEUE IPT_ALIGN(sizeof(ipt_nfqueue_info_t)) -#define SIZE_TOTAL SIZE_ENTRY + SIZE_TCP_MATCH + SIZE_UDP_MATCH + SIZE_CGROUP_MATCH \ - + SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH + SIZE_TARGET \ - + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG + SIZE_TARGET_NFQUEUE +#define SIZE_TOTAL SIZE_ENTRY + SIZE_MARK_MATCH + SIZE_TCP_MATCH + SIZE_UDP_MATCH \ + + SIZE_CGROUP_MATCH + SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH \ + + SIZE_TARGET + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG + SIZE_TARGET_NFQUEUE static unsigned int __add_match(const char *name, ipt_entry_match_t *start, int revision, size_t size, void *data) @@ -148,6 +152,18 @@ static void __add_iprange(unsigned char *entry, unsigned int *size_match, iptabl e->next_offset += SIZE_IPRANGE_MATCH; } +static unsigned int __add_mark_match(uint32_t mask, uint32_t compare, ipt_entry_match_t *start) +{ + ipt_mark_info_t mark; + memset(&mark, 0, sizeof(ipt_mark_info_t)); + + mark.mask = mask; + mark.mark = compare; + + /* match_mark => "-m mark" */ + return __add_match(IPTC_MARK, start, 1, sizeof(ipt_mark_info_t), &mark); +} + static unsigned int __add_port_match(iptables_protocol_type_e prot_type, iptables_port_type_e sport_type, unsigned short sport1, unsigned short sport2, iptables_port_type_e dport_type, unsigned short dport1, unsigned short dport2, @@ -391,6 +407,14 @@ static int __create_entry_data(unsigned char *entry, unsigned char *mask, rule->d_ip_type == IPTABLES_IP_RANGE) __add_iprange(entry, &size_match, rule); + /* -m mark */ + if (rule->mark_flag_mask > 0) { + size_match += __add_mark_match(rule->mark_flag_mask, rule->mark_flag_compare, + (ipt_entry_match_t *) (e->elems + size_match)); + e->target_offset += SIZE_MARK_MATCH; + e->next_offset += SIZE_MARK_MATCH; + } + /* -p tcp */ switch (rule->protocol) { case IPTABLES_PROTOCOL_TCP: diff --git a/src/helper/helper-iptables.h b/src/helper/helper-iptables.h index 564a4f6..73c4573 100755 --- a/src/helper/helper-iptables.h +++ b/src/helper/helper-iptables.h @@ -81,6 +81,8 @@ typedef struct { iptables_protocol_type_e protocol; unsigned char tcp_flag_mask; unsigned char tcp_flag_compare; + uint32_t mark_flag_mask; + uint32_t mark_flag_compare; struct in_addr s_ip1; struct in_addr s_ip2; struct in_addr d_ip1; diff --git a/src/stc-iptables-util.c b/src/stc-iptables-util.c index 48beeee..52a696a 100755 --- a/src/stc-iptables-util.c +++ b/src/stc-iptables-util.c @@ -31,8 +31,10 @@ #define RULE_CGROUP "cgroup" #define RULE_NFACCT "nfacct" #define RULE_PROTOCOL "protocol" -#define RULE_MASK "tcp_flag_mask" -#define RULE_COMPARE "tcp_flag_compare" +#define RULE_TCP_MASK "tcp_flag_mask" +#define RULE_TCP_COMPARE "tcp_flag_compare" +#define RULE_MARK_MASK "mark_flag_mask" +#define RULE_MARK_COMPARE "mark_flag_compare" #define RULE_TARGET "target" #define RULE_TARGETTYPE "target_type" @@ -179,18 +181,26 @@ void __stc_extract_rule(const char *key, GVariant *value, rule->protocol = g_variant_get_uint16(value); STC_LOGD("%s: [%u]", RULE_PROTOCOL, rule->protocol); - } else if (!g_strcmp0(key, RULE_MASK)) { + } else if (!g_strcmp0(key, RULE_TCP_MASK)) { if (rule->protocol == IPTABLES_PROTOCOL_TCP) { rule->tcp_flag_mask = g_variant_get_byte(value); - STC_LOGD("%s: [%u]", RULE_MASK, rule->tcp_flag_mask); + STC_LOGD("%s: [%u]", RULE_TCP_MASK, rule->tcp_flag_mask); } - } else if (!g_strcmp0(key, RULE_COMPARE)) { + } else if (!g_strcmp0(key, RULE_TCP_COMPARE)) { if (rule->protocol == IPTABLES_PROTOCOL_TCP) { rule->tcp_flag_compare = g_variant_get_byte(value); - STC_LOGD("%s: [%u]", RULE_COMPARE, rule->tcp_flag_compare); + STC_LOGD("%s: [%u]", RULE_TCP_COMPARE, rule->tcp_flag_compare); } + } else if (!g_strcmp0(key, RULE_MARK_MASK)) { + rule->mark_flag_mask = g_variant_get_uint32(value); + STC_LOGD("%s: [%u]", RULE_MARK_MASK, rule->mark_flag_mask); + + } else if (!g_strcmp0(key, RULE_MARK_COMPARE)) { + rule->mark_flag_compare = g_variant_get_uint32(value); + STC_LOGD("%s: [%u]", RULE_MARK_COMPARE, rule->mark_flag_compare); + } else if (!g_strcmp0(key, RULE_TARGET)) { gsize len = 0; rule->target = g_variant_dup_string(value, &len); @@ -383,18 +393,26 @@ void __stc_extract_6_rule(const char *key, GVariant *value, rule->protocol = g_variant_get_uint16(value); STC_LOGD("%s: [%u]", RULE_PROTOCOL, rule->protocol); - } else if (!g_strcmp0(key, RULE_MASK)) { + } else if (!g_strcmp0(key, RULE_TCP_MASK)) { if (rule->protocol == IP6TABLES_PROTOCOL_TCP) { rule->tcp_flag_mask = g_variant_get_byte(value); - STC_LOGD("%s: [%u]", RULE_MASK, rule->tcp_flag_mask); + STC_LOGD("%s: [%u]", RULE_TCP_MASK, rule->tcp_flag_mask); } - } else if (!g_strcmp0(key, RULE_COMPARE)) { + } else if (!g_strcmp0(key, RULE_TCP_COMPARE)) { if (rule->protocol == IP6TABLES_PROTOCOL_TCP) { rule->tcp_flag_compare = g_variant_get_byte(value); - STC_LOGD("%s: [%u]", RULE_COMPARE, rule->tcp_flag_compare); + STC_LOGD("%s: [%u]", RULE_TCP_COMPARE, rule->tcp_flag_compare); } + } else if (!g_strcmp0(key, RULE_MARK_MASK)) { + rule->mark_flag_mask = g_variant_get_uint32(value); + STC_LOGD("%s: [%u]", RULE_MARK_MASK, rule->mark_flag_mask); + + } else if (!g_strcmp0(key, RULE_MARK_COMPARE)) { + rule->mark_flag_compare = g_variant_get_uint32(value); + STC_LOGD("%s: [%u]", RULE_MARK_COMPARE, rule->mark_flag_compare); + } else if (!g_strcmp0(key, RULE_TARGET)) { gsize len = 0; rule->target = g_variant_dup_string(value, &len);