Implement mark matching sandbox/mmajewski2/doze_related_improvements
authorMateusz Majewski <m.majewski2@samsung.com>
Thu, 14 Jan 2021 14:08:38 +0000 (15:08 +0100)
committerMateusz Majewski <m.majewski2@samsung.com>
Thu, 14 Jan 2021 14:08:52 +0000 (15:08 +0100)
Change-Id: Ib947ef47cc684c1a7e9e0aaa985ae0ed7400bf26

src/helper/helper-ip6tables.c
src/helper/helper-ip6tables.h
src/helper/helper-iptables.c
src/helper/helper-iptables.h
src/stc-iptables-util.c

index edd06bb210d66e625431cc7af92fbcedbbce230d..8b70dc6efaa267033517028bd7901a480c454cb6 100755 (executable)
@@ -23,6 +23,7 @@
 #include <xtables.h>
 
 #include <linux/netfilter.h>
+#include <linux/netfilter/xt_mark.h>
 #include <linux/netfilter/xt_cgroup.h>
 #include <linux/netfilter/xt_nfacct.h>
 #include <linux/netfilter/xt_iprange.h>
@@ -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;
index b6177bd14257a554d0d7c29f7828c13373fa9f9e..760b265d7a8540a5bb4ca24aa9c3ac0383abf4e6 100755 (executable)
@@ -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;
index e0318c88585a955b37303b7df422dbac8328da41..cbdf7c9438daeebcce9195e7c563a8934ec9abb4 100755 (executable)
@@ -23,6 +23,7 @@
 #include <arpa/inet.h>
 
 #include <linux/netfilter.h>
+#include <linux/netfilter/xt_mark.h>
 #include <linux/netfilter/xt_cgroup.h>
 #include <linux/netfilter/xt_nfacct.h>
 #include <linux/netfilter/xt_iprange.h>
@@ -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:
index 564a4f687e3d75a6c8291eeaf5e8388f09d305e5..73c4573c27c415251e821be040410b0df2946e3f 100755 (executable)
@@ -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;
index 48beeeec6c0fd649d1ecf5b073e97ec4ab34e73f..52a696a3c876232619dd1a15ecdaddcabf55097f 100755 (executable)
 #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);