#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>
#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"
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;
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))
#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)
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,
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;
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;
#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>
#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"
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;
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))
#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)
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,
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:
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;
#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"
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);
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);