Add to insert rule function 19/187419/2
authorhyunuktak <hyunuk.tak@samsung.com>
Thu, 23 Aug 2018 05:45:44 +0000 (14:45 +0900)
committerhyunuktak <hyunuk.tak@samsung.com>
Fri, 24 Aug 2018 04:34:01 +0000 (13:34 +0900)
Change-Id: I933ca377bb7750df1b77d02381e780edb85c76de
Signed-off-by: hyunuktak <hyunuk.tak@samsung.com>
include/stc-iptables-util.h
interfaces/stc-iptables-iface.xml
packaging/stc-iptables.spec
src/helper/helper-ip6tables.c
src/helper/helper-ip6tables.h
src/helper/helper-iptables.c
src/helper/helper-iptables.h
src/stc-iptables-gdbus.c
src/stc-iptables-util.c

index 16506ef..b79f86c 100755 (executable)
@@ -72,6 +72,11 @@ gboolean handle_iptables_add_rule(StcRule *object,
                               GVariant *rule,
                               void *user_data);
 
+gboolean handle_iptables_insert_rule(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule,
+                              void *user_data);
+
 gboolean handle_iptables_remove_rule(StcRule *object,
                               GDBusMethodInvocation *invocation,
                               GVariant *rule,
@@ -98,6 +103,11 @@ gboolean handle_ip6tables_add_rule(StcRule *object,
                               GVariant *rule,
                               void *user_data);
 
+gboolean handle_ip6tables_insert_rule(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule,
+                              void *user_data);
+
 gboolean handle_ip6tables_remove_rule(StcRule *object,
                               GDBusMethodInvocation *invocation,
                               GVariant *rule,
index 0e3ee98..6b3415b 100755 (executable)
                        <arg type='a{sv}' name='rules' direction='in'/>
                        <arg type='i' name='error_code' direction='out'/>
                </method>
+               <method name='IptInsertRule'>
+                       <arg type='a{sv}' name='rules' direction='in'/>
+                       <arg type='i' name='error_code' direction='out'/>
+               </method>
                <method name='IptRemoveRule'>
                        <arg type='a{sv}' name='rules' direction='in'/>
                        <arg type='i' name='error_code' direction='out'/>
                        <arg type='a{sv}' name='rules' direction='in'/>
                        <arg type='i' name='error_code' direction='out'/>
                </method>
+               <method name='Ip6tInsertRule'>
+                       <arg type='a{sv}' name='rules' direction='in'/>
+                       <arg type='i' name='error_code' direction='out'/>
+               </method>
                <method name='Ip6tRemoveRule'>
                        <arg type='a{sv}' name='rules' direction='in'/>
                        <arg type='i' name='error_code' direction='out'/>
index 16c1f2e..346c4c0 100644 (file)
@@ -1,6 +1,6 @@
 Name:       stc-iptables
 Summary:    STC(Smart Traffic Control) iptables
-Version:    0.0.18
+Version:    0.0.19
 Release:    0
 Group:      Network & Connectivity/Other
 License:    GPL-2.0 and Apache-2.0
@@ -66,7 +66,7 @@ cp resources/dbus/stc-iptables.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/s
 mkdir -p /opt/usr/data/network
 chmod 755 /opt/usr/data/network
 chown network_fw:network_fw /opt/usr/data/network
-#/usr/sbin/setcap cap_net_bind_service,cap_net_raw,cap_net_admin=ei %{_bindir}/stc-iptables
+/usr/sbin/setcap cap_net_bind_service,cap_net_raw,cap_net_admin=ei %{_bindir}/stc-iptables
 
 %files
 %manifest %{name}.manifest
index d458783..352bca7 100755 (executable)
@@ -43,6 +43,8 @@
 
 #define IP6TC_MASK   "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"
 
+#define IP6TC_INSERT_RULENUM 0
+
 /* handle */
 typedef struct xtc_handle            ip6t_handle_t;
 
@@ -499,6 +501,55 @@ int ip6tables_add_rule(ip6tables_rule_s *rule)
        return STC_ERROR_NONE;
 }
 
+int ip6tables_insert_rule(ip6tables_rule_s *rule)
+{
+       ip6t_handle_t *handle;
+       unsigned char entry[SIZE_TOTAL] = {0, };
+       unsigned char mask[SIZE_TOTAL] = {0, };
+
+       const char *chain = rule->chain;
+
+       if (__create_entry_data(entry, mask, rule) != 0) {
+               STC_LOGE("Failed to create entry"); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       handle = ip6tc_init(IP6TC_TABLE);
+       if (handle == NULL) {
+               STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       if (!ip6tc_is_chain(chain, handle)) {
+               STC_LOGW("chain not present [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
+               ip6tc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
+               STC_LOGW("Entry already present"); //LCOV_EXCL_LINE
+               ip6tc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_NONE; //LCOV_EXCL_LINE
+       }
+
+       if (!ip6tc_insert_entry(chain, (const ip6t_entry_t *)entry, IP6TC_INSERT_RULENUM, handle)) {
+               STC_LOGW("ip6tc_insert_entry failed [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
+               ip6tc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       if (!ip6tc_commit(handle)) {
+               STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); //LCOV_EXCL_LINE
+               ip6tc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       ip6tc_free(handle);
+
+       STC_LOGI("Success adding rule");
+       return STC_ERROR_NONE;
+}
+
 int ip6tables_remove_rule(ip6tables_rule_s *rule)
 {
        ip6t_handle_t *handle;
index d60f991..8da2f64 100755 (executable)
@@ -105,6 +105,12 @@ typedef struct {
 int ip6tables_add_rule(ip6tables_rule_s *rule);
 
 /**
+ * @desc This function inserts a new ip6tables rule.
+ * @return 0 on success and negative value if error.
+ */
+int ip6tables_insert_rule(ip6tables_rule_s *rule);
+
+/**
  * @desc This function removes already set ip6tables rule.
  * @return 0 on success and negative value if error.
  */
index 2f564dc..7fd5a73 100755 (executable)
@@ -42,6 +42,8 @@
 
 #define IPTC_MASK    "255.255.255.255"
 
+#define IPTC_INSERT_RULENUM 0
+
 /* handle */
 typedef struct xtc_handle            ipt_handle_t;
 
@@ -161,6 +163,8 @@ static unsigned int __add_port_match(iptables_protocol_type_e prot_type,
                                tcp.spts[1] = ntohs(htons(sport2));
                                break;
                        default:
+                               tcp.spts[0] = 0x0000;
+                               tcp.spts[1] = 0xFFFF;
                                break;
                        }
                        switch(dport_type) {
@@ -175,6 +179,8 @@ static unsigned int __add_port_match(iptables_protocol_type_e prot_type,
                                tcp.dpts[1] = ntohs(htons(dport2));
                                break;
                        default:
+                               tcp.dpts[0] = 0x0000;
+                               tcp.dpts[1] = 0xFFFF;
                                break;
                        }
                        return __add_match(IPTC_TCP, start, 0, sizeof(ipt_tcp_info_t), &tcp);
@@ -195,6 +201,8 @@ static unsigned int __add_port_match(iptables_protocol_type_e prot_type,
                                udp.spts[1] = ntohs(htons(sport2));
                                break;
                        default:
+                               udp.spts[0] = 0x0000;
+                               udp.spts[1] = 0xFFFF;
                                break;
                        }
                        switch(dport_type) {
@@ -209,6 +217,8 @@ static unsigned int __add_port_match(iptables_protocol_type_e prot_type,
                                udp.dpts[1] = ntohs(htons(dport2));
                                break;
                        default:
+                               udp.dpts[0] = 0x0000;
+                               udp.dpts[1] = 0xFFFF;
                                break;
                        }
                        return __add_match(IPTC_UDP, start, 0, sizeof(ipt_udp_info_t), &udp);
@@ -482,6 +492,55 @@ int iptables_add_rule(iptables_rule_s *rule)
        return STC_ERROR_NONE;
 }
 
+int iptables_insert_rule(iptables_rule_s *rule)
+{
+       ipt_handle_t *handle;
+       unsigned char entry[SIZE_TOTAL] = {0, };
+       unsigned char mask[SIZE_TOTAL] = {0, };
+
+       const char *chain = rule->chain;
+
+       if (__create_entry_data(entry, mask, rule) != 0) {
+               STC_LOGE("Failed to create entry"); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       handle = iptc_init(IPTC_TABLE);
+       if (handle == NULL) {
+               STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       if (!iptc_is_chain(chain, handle)) {
+               STC_LOGW("chain not present [%s]", iptc_strerror(errno)); //LCOV_EXCL_LINE
+               iptc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       if (iptc_check_entry(chain, (const ipt_entry_t *)entry, mask, handle)) {
+               STC_LOGW("Entry already present"); //LCOV_EXCL_LINE
+               iptc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_NONE; //LCOV_EXCL_LINE
+       }
+
+       if (!iptc_insert_entry(chain, (const ipt_entry_t *)entry, IPTC_INSERT_RULENUM, handle)) {
+               STC_LOGW("iptc_insert_entry failed [%s]", iptc_strerror(errno)); //LCOV_EXCL_LINE
+               iptc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       if (!iptc_commit(handle)) {
+               STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); //LCOV_EXCL_LINE
+               iptc_free(handle); //LCOV_EXCL_LINE
+               return STC_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+       }
+
+       iptc_free(handle);
+
+       STC_LOGI("Success inserting rule");
+       return STC_ERROR_NONE;
+}
+
 int iptables_remove_rule(iptables_rule_s *rule)
 {
        ipt_handle_t *handle;
index eafa6e1..58a36cf 100755 (executable)
@@ -105,6 +105,12 @@ typedef struct {
 int iptables_add_rule(iptables_rule_s *rule);
 
 /**
+ * @desc This function inserts a new iptables rule.
+ * @return 0 on success and negative value if error.
+ */
+int iptables_insert_rule(iptables_rule_s *rule);
+
+/**
  * @desc This function removes already set iptables rule.
  * @return 0 on success and negative value if error.
  */
index 4770e1d..070bc27 100755 (executable)
@@ -124,6 +124,10 @@ static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables)
                         G_CALLBACK(handle_iptables_add_rule),
                         stc_iptables);
 
+       g_signal_connect(rule, "handle-ipt-insert-rule",
+                        G_CALLBACK(handle_iptables_insert_rule),
+                        stc_iptables);
+
        g_signal_connect(rule, "handle-ipt-remove-rule",
                         G_CALLBACK(handle_iptables_remove_rule),
                         stc_iptables);
@@ -132,6 +136,10 @@ static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables)
                         G_CALLBACK(handle_ip6tables_add_rule),
                         stc_iptables);
 
+       g_signal_connect(rule, "handle-ip6t-insert-rule",
+                        G_CALLBACK(handle_ip6tables_add_rule),
+                        stc_iptables);
+
        g_signal_connect(rule, "handle-ip6t-remove-rule",
                         G_CALLBACK(handle_ip6tables_remove_rule),
                         stc_iptables);
index 93cd57c..46582d2 100755 (executable)
@@ -131,25 +131,25 @@ void __stc_extract_rule(const char *key, GVariant *value,
                }
 
        } else if (!g_strcmp0(key, RULE_SPORT1)) {
-               if (rule->s_ip_type != IPTABLES_IP_NONE) {
+               if (rule->s_port_type != IPTABLES_PORT_NONE) {
                        rule->s_port1 = g_variant_get_uint32(value);
                        STC_LOGD("%s: [%04x]", RULE_SPORT1, rule->s_port1);
                }
 
        } else if (!g_strcmp0(key, RULE_SPORT2)) {
-               if (rule->s_ip_type != IPTABLES_IP_NONE) {
+               if (rule->s_port_type != IPTABLES_PORT_NONE) {
                        rule->s_port2 = g_variant_get_uint32(value);
                        STC_LOGD("%s: [%04x]", RULE_SPORT2, rule->s_port2);
                }
 
        } else if (!g_strcmp0(key, RULE_DPORT1)) {
-               if (rule->d_ip_type != IPTABLES_IP_NONE) {
+               if (rule->d_port_type != IPTABLES_PORT_NONE) {
                        rule->d_port1 = g_variant_get_uint32(value);
                        STC_LOGD("%s: [%04x]", RULE_DPORT1, rule->d_port1);
                }
 
        } else if (!g_strcmp0(key, RULE_DPORT2)) {
-               if (rule->d_ip_type != IPTABLES_IP_NONE) {
+               if (rule->d_port_type != IPTABLES_PORT_NONE) {
                        rule->d_port2 = g_variant_get_uint32(value);
                        STC_LOGD("%s: [%04x]", RULE_DPORT2, rule->d_port2);
                }
@@ -259,69 +259,87 @@ void __stc_extract_6_rule(const char *key, GVariant *value,
                STC_LOGD("%s: [%u]", RULE_DPORTTYPE, rule->d_port_type);
 
        } else if (!g_strcmp0(key, RULE_SIP1)) {
-               gsize len = 0;
-               char *str = g_variant_dup_string(value, &len);
-               sscanf(str, "%08x:%08x:%08x:%08x",
-                       &(rule->s_ip1.s6_addr32[0]), &(rule->s_ip1.s6_addr32[1]),
-                       &(rule->s_ip1.s6_addr32[2]), &(rule->s_ip1.s6_addr32[3]));
-               STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP1,
-                       rule->s_ip1.s6_addr32[0], rule->s_ip1.s6_addr32[1],
-                       rule->s_ip1.s6_addr32[2], rule->s_ip1.s6_addr32[3]);
-               FREE(str);
+               if (rule->s_ip_type != IPTABLES_IP_NONE) {
+                       gsize len = 0;
+                       char *str = g_variant_dup_string(value, &len);
+                       sscanf(str, "%08x:%08x:%08x:%08x",
+                               &(rule->s_ip1.s6_addr32[0]), &(rule->s_ip1.s6_addr32[1]),
+                               &(rule->s_ip1.s6_addr32[2]), &(rule->s_ip1.s6_addr32[3]));
+                       STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP1,
+                               rule->s_ip1.s6_addr32[0], rule->s_ip1.s6_addr32[1],
+                               rule->s_ip1.s6_addr32[2], rule->s_ip1.s6_addr32[3]);
+                       FREE(str);
+               }
 
        } else if (!g_strcmp0(key, RULE_SIP2)) {
-               gsize len = 0;
-               char *str = g_variant_dup_string(value, &len);
-               sscanf(str, "%08x:%08x:%08x:%08x",
-                       &(rule->s_ip2.s6_addr32[0]), &(rule->s_ip2.s6_addr32[1]),
-                       &(rule->s_ip2.s6_addr32[2]), &(rule->s_ip2.s6_addr32[3]));
-               STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP2,
-                       rule->s_ip2.s6_addr32[0], rule->s_ip2.s6_addr32[1],
-                       rule->s_ip2.s6_addr32[2], rule->s_ip2.s6_addr32[3]);
-               FREE(str);
+               if (rule->s_ip_type != IPTABLES_IP_NONE) {
+                       gsize len = 0;
+                       char *str = g_variant_dup_string(value, &len);
+                       sscanf(str, "%08x:%08x:%08x:%08x",
+                               &(rule->s_ip2.s6_addr32[0]), &(rule->s_ip2.s6_addr32[1]),
+                               &(rule->s_ip2.s6_addr32[2]), &(rule->s_ip2.s6_addr32[3]));
+                       STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP2,
+                               rule->s_ip2.s6_addr32[0], rule->s_ip2.s6_addr32[1],
+                               rule->s_ip2.s6_addr32[2], rule->s_ip2.s6_addr32[3]);
+                       FREE(str);
+               }
 
        } else if (!g_strcmp0(key, RULE_DIP1)) {
-               gsize len = 0;
-               char *str = g_variant_dup_string(value, &len);
-               sscanf(str, "%08x:%08x:%08x:%08x",
-                       &(rule->d_ip1.s6_addr32[0]), &(rule->d_ip1.s6_addr32[1]),
-                       &(rule->d_ip1.s6_addr32[2]), &(rule->d_ip1.s6_addr32[3]));
-               STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP1,
-                       rule->d_ip1.s6_addr32[0], rule->d_ip1.s6_addr32[1],
-                       rule->d_ip1.s6_addr32[2], rule->d_ip1.s6_addr32[3]);
-               FREE(str);
+               if (rule->d_ip_type != IPTABLES_IP_NONE) {
+                       gsize len = 0;
+                       char *str = g_variant_dup_string(value, &len);
+                       sscanf(str, "%08x:%08x:%08x:%08x",
+                               &(rule->d_ip1.s6_addr32[0]), &(rule->d_ip1.s6_addr32[1]),
+                               &(rule->d_ip1.s6_addr32[2]), &(rule->d_ip1.s6_addr32[3]));
+                       STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP1,
+                               rule->d_ip1.s6_addr32[0], rule->d_ip1.s6_addr32[1],
+                               rule->d_ip1.s6_addr32[2], rule->d_ip1.s6_addr32[3]);
+                       FREE(str);
+               }
 
        } else if (!g_strcmp0(key, RULE_DIP2)) {
-               gsize len = 0;
-               char *str = g_variant_dup_string(value, &len);
-               sscanf(str, "%08x:%08x:%08x:%08x",
-                       &(rule->d_ip2.s6_addr32[0]), &(rule->d_ip2.s6_addr32[1]),
-                       &(rule->d_ip2.s6_addr32[2]), &(rule->d_ip2.s6_addr32[3]));
-               STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP2,
-                       rule->d_ip2.s6_addr32[0], rule->d_ip2.s6_addr32[1],
-                       rule->d_ip2.s6_addr32[2], rule->d_ip2.s6_addr32[3]);
-               FREE(str);
+               if (rule->d_ip_type != IPTABLES_IP_NONE) {
+                       gsize len = 0;
+                       char *str = g_variant_dup_string(value, &len);
+                       sscanf(str, "%08x:%08x:%08x:%08x",
+                               &(rule->d_ip2.s6_addr32[0]), &(rule->d_ip2.s6_addr32[1]),
+                               &(rule->d_ip2.s6_addr32[2]), &(rule->d_ip2.s6_addr32[3]));
+                       STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP2,
+                               rule->d_ip2.s6_addr32[0], rule->d_ip2.s6_addr32[1],
+                               rule->d_ip2.s6_addr32[2], rule->d_ip2.s6_addr32[3]);
+                       FREE(str);
+               }
 
        } else if (!g_strcmp0(key, RULE_SPORT1)) {
-               rule->s_port1 = g_variant_get_uint32(value);
-               STC_LOGD("%s: [%04x]", RULE_SPORT1, rule->s_port1);
+               if (rule->s_port_type != IPTABLES_PORT_NONE) {
+                       rule->s_port1 = g_variant_get_uint32(value);
+                       STC_LOGD("%s: [%04x]", RULE_SPORT1, rule->s_port1);
+               }
 
        } else if (!g_strcmp0(key, RULE_SPORT2)) {
-               rule->s_port2 = g_variant_get_uint32(value);
-               STC_LOGD("%s: [%04x]", RULE_SPORT2, rule->s_port2);
+               if (rule->s_port_type != IPTABLES_PORT_NONE) {
+                       rule->s_port2 = g_variant_get_uint32(value);
+                       STC_LOGD("%s: [%04x]", RULE_SPORT2, rule->s_port2);
+               }
 
        } else if (!g_strcmp0(key, RULE_DPORT1)) {
-               rule->d_port1 = g_variant_get_uint32(value);
-               STC_LOGD("%s: [%04x]", RULE_DPORT1, rule->d_port1);
+               if (rule->d_port_type != IPTABLES_PORT_NONE) {
+                       rule->d_port1 = g_variant_get_uint32(value);
+                       STC_LOGD("%s: [%04x]", RULE_DPORT1, rule->d_port1);
+               }
 
        } else if (!g_strcmp0(key, RULE_DPORT2)) {
-               rule->d_port2 = g_variant_get_uint32(value);
-               STC_LOGD("%s: [%04x]", RULE_DPORT2, rule->d_port2);
+               if (rule->d_port_type != IPTABLES_PORT_NONE) {
+                       rule->d_port2 = g_variant_get_uint32(value);
+                       STC_LOGD("%s: [%04x]", RULE_DPORT2, rule->d_port2);
+               }
 
        } else if (!g_strcmp0(key, RULE_IFNAME)) {
-               gsize len = 0;
-               rule->ifname = g_variant_dup_string(value, &len);
-               STC_LOGD("%s: [%s]", RULE_IFNAME, rule->ifname);
+               if (rule->direction != IPTABLES_DIRECTION_NONE) {
+                       gsize len = 0;
+                       rule->ifname = g_variant_dup_string(value, &len);
+                       STC_LOGD("%s: [%s]", RULE_IFNAME, rule->ifname);
+               }
 
        } else if (!g_strcmp0(key, RULE_CGROUP)) {
                rule->classid = g_variant_get_uint32(value);
@@ -346,30 +364,42 @@ void __stc_extract_6_rule(const char *key, GVariant *value,
                STC_LOGD("%s: [%u]", RULE_TARGETTYPE, rule->target_type);
 
        } else if (!g_strcmp0(key, RULE_LOG_LEVEL)) {
-               rule->log_level = g_variant_get_uint16(value);
-               STC_LOGD("%s: [%u]", RULE_LOG_LEVEL, rule->log_level);
+               if (rule->target_type == IPTABLES_ACTION_LOG) {
+                       rule->log_level = g_variant_get_uint16(value);
+                       STC_LOGD("%s: [%u]", RULE_LOG_LEVEL, rule->log_level);
+               }
 
        } else if (!g_strcmp0(key, RULE_LOG_PREFIX)) {
-               gsize len = 0;
-               rule->log_prefix = g_variant_dup_string(value, &len);
-               STC_LOGD("%s: [%s]", RULE_LOG_PREFIX, rule->log_prefix);
+               if (rule->target_type == IPTABLES_ACTION_LOG) {
+                       gsize len = 0;
+                       rule->log_prefix = g_variant_dup_string(value, &len);
+                       STC_LOGD("%s: [%s]", RULE_LOG_PREFIX, rule->log_prefix);
+               }
 
        } else if (!g_strcmp0(key, RULE_NFLOG_GROUP)) {
-               rule->nflog_group = g_variant_get_uint16(value);
-               STC_LOGD("%s: [%u]", RULE_NFLOG_GROUP, rule->nflog_group);
+               if (rule->target_type == IPTABLES_ACTION_NFLOG) {
+                       rule->nflog_group = g_variant_get_uint16(value);
+                       STC_LOGD("%s: [%u]", RULE_NFLOG_GROUP, rule->nflog_group);
+               }
 
        } else if (!g_strcmp0(key, RULE_NFLOG_PREFIX)) {
-               gsize len = 0;
-               rule->nflog_prefix = g_variant_dup_string(value, &len);
-               STC_LOGD("%s: [%s]", RULE_NFLOG_PREFIX, rule->nflog_prefix);
+               if (rule->target_type == IPTABLES_ACTION_NFLOG) {
+                       gsize len = 0;
+                       rule->nflog_prefix = g_variant_dup_string(value, &len);
+                       STC_LOGD("%s: [%s]", RULE_NFLOG_PREFIX, rule->nflog_prefix);
+               }
 
        } else if (!g_strcmp0(key, RULE_NFLOG_RANGE)) {
-               rule->nflog_range = g_variant_get_uint16(value);
-               STC_LOGD("%s: [%u]", RULE_NFLOG_RANGE, rule->nflog_range);
+               if (rule->target_type == IPTABLES_ACTION_NFLOG) {
+                       rule->nflog_range = g_variant_get_uint16(value);
+                       STC_LOGD("%s: [%u]", RULE_NFLOG_RANGE, rule->nflog_range);
+               }
 
        } else if (!g_strcmp0(key, RULE_NFLOG_THRESHOLD)) {
-               rule->nflog_threshold = g_variant_get_uint16(value);
-               STC_LOGD("%s: [%u]", RULE_NFLOG_THRESHOLD, rule->nflog_threshold);
+               if (rule->target_type == IPTABLES_ACTION_NFLOG) {
+                       rule->nflog_threshold = g_variant_get_uint16(value);
+                       STC_LOGD("%s: [%u]", RULE_NFLOG_THRESHOLD, rule->nflog_threshold);
+               }
 
        } else {
                STC_LOGD("Unknown rule [%s]", key); //LCOV_EXCL_LINE
@@ -474,6 +504,63 @@ gboolean handle_iptables_add_rule(StcRule *object,
        return TRUE;
 }
 
+gboolean handle_iptables_insert_rule(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rules,
+                              void *user_data)
+{
+       __STC_LOG_FUNC_ENTER__;
+       stc_error_e ret = STC_ERROR_NONE;
+       GVariant *return_parameters = NULL;
+
+       if (rules != NULL) {
+               GVariantIter *iter = NULL;
+
+               g_variant_get(rules, "a{sv}", &iter);
+
+               iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1);
+               if (rule != NULL) {
+                       memset(rule, 0, sizeof(iptables_rule_s));
+
+                       stc_iptables_gdbus_dict_foreach(iter,
+                                                       __stc_extract_rule,
+                                                       rule);
+
+                       ret = iptables_insert_rule(rule);
+                       if (ret != STC_ERROR_NONE) {
+                                //LCOV_EXCL_START
+                               STC_LOGE("Failed insert rule [%s:%d:%s:%d:%s:%s]", rule->chain,
+                                        rule->direction, rule->ifname, rule->classid,
+                                        rule->nfacct_name, rule->target);
+
+                               __free_rule(rule);
+
+                               STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret);
+                               __STC_LOG_FUNC_EXIT__;
+                               return TRUE;
+                                //LCOV_EXCL_STOP
+                       }
+
+                       __free_rule(rule);
+               }
+
+               g_variant_iter_free(iter);
+       } else {
+               STC_IPTABLES_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
+                                             STC_ERROR_INVALID_PARAMETER);
+               __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return TRUE; //LCOV_EXCL_LINE
+       }
+
+       return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
+
+       STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
+       STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
+
+       __STC_LOG_FUNC_EXIT__;
+       return TRUE;
+}
+
 gboolean handle_iptables_remove_rule(StcRule *object,
                               GDBusMethodInvocation *invocation,
                               GVariant *rules,
@@ -662,6 +749,63 @@ gboolean handle_ip6tables_add_rule(StcRule *object,
        return TRUE;
 }
 
+gboolean handle_ip6tables_insert_rule(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rules,
+                              void *user_data)
+{
+       __STC_LOG_FUNC_ENTER__;
+       stc_error_e ret = STC_ERROR_NONE;
+       GVariant *return_parameters = NULL;
+
+       if (rules != NULL) {
+               GVariantIter *iter = NULL;
+
+               g_variant_get(rules, "a{sv}", &iter);
+
+               ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1);
+               if (rule != NULL) {
+                       memset(rule, 0, sizeof(ip6tables_rule_s));
+
+                       stc_iptables_gdbus_dict_foreach(iter,
+                                                       __stc_extract_6_rule,
+                                                       rule);
+
+                       ret = ip6tables_insert_rule(rule);
+                       if (ret != STC_ERROR_NONE) {
+                                //LCOV_EXCL_START
+                               STC_LOGE("Failed insert rule [%s:%d:%s:%d:%s:%s]", rule->chain,
+                                        rule->direction, rule->ifname, rule->classid,
+                                        rule->nfacct_name, rule->target);
+
+                               __free_6_rule(rule);
+
+                               STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret);
+                               __STC_LOG_FUNC_EXIT__;
+                               return TRUE;
+                                //LCOV_EXCL_STOP
+                       }
+
+                       __free_6_rule(rule);
+               }
+
+               g_variant_iter_free(iter);
+       } else {
+               STC_IPTABLES_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
+                                             STC_ERROR_INVALID_PARAMETER);
+               __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return TRUE; //LCOV_EXCL_LINE
+       }
+
+       return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
+
+       STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
+       STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
+
+       __STC_LOG_FUNC_EXIT__;
+       return TRUE;
+}
+
 gboolean handle_ip6tables_remove_rule(StcRule *object,
                               GDBusMethodInvocation *invocation,
                               GVariant *rules,