Add to add/remove rule list 95/237395/1 accepted/tizen_5.5_unified accepted/tizen_5.5_unified_wearable_hotfix tizen_5.5 tizen_5.5_wearable_hotfix accepted/tizen/5.5/unified/20200630.160559 accepted/tizen/5.5/unified/wearable/hotfix/20201027.115041 submit/tizen_5.5/20200630.071105 submit/tizen_5.5_wearable_hotfix/20201026.184303
authorhyunuk.tak <hyunuk.tak@samsung.com>
Thu, 21 May 2020 07:29:38 +0000 (16:29 +0900)
committerCheoleun Moon <chleun.moon@samsung.com>
Tue, 30 Jun 2020 04:52:10 +0000 (13:52 +0900)
Change-Id: I2a2aa9339215d95d84fda7086355f274e7e1f978
Signed-off-by: hyunuk.tak <hyunuk.tak@samsung.com>
include/stc-iptables-util.h
interfaces/stc-iptables-iface.xml
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 41d929d..c823cd4 100755 (executable)
@@ -87,6 +87,16 @@ gboolean handle_iptables_flush_chain(StcChain *object,
                               const gchar *chain,
                               void *user_data);
 
+gboolean handle_iptables_add_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data);
+
+gboolean handle_iptables_remove_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data);
+
 /* ip6tables */
 gboolean handle_ip6tables_add_rule(StcRule *object,
                               GDBusMethodInvocation *invocation,
@@ -118,4 +128,14 @@ gboolean handle_ip6tables_flush_chain(StcChain *object,
                               const gchar *chain,
                               void *user_data);
 
+gboolean handle_ip6tables_add_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data);
+
+gboolean handle_ip6tables_remove_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data);
+
 #endif /* __STC_IPTABLES_UTIL_H__ */
index 6b3415b..8c9f6c0 100755 (executable)
@@ -9,6 +9,14 @@
                </method>
        </interface>
        <interface name="net.stc.iptables.rule">
+               <method name='IptAddList'>
+                       <arg type='aa{sv}' name='rule_list' direction='in'/>
+                       <arg type='i' name='error_code' direction='out'/>
+               </method>
+               <method name='Ip6tAddList'>
+                       <arg type='aa{sv}' name='rule_list' direction='in'/>
+                       <arg type='i' name='error_code' direction='out'/>
+               </method>
                <method name='IptAddRule'>
                        <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='IptRemoveList'>
+                       <arg type='aa{sv}' name='rule_list' direction='in'/>
+                       <arg type='i' name='error_code' direction='out'/>
+               </method>
+               <method name='Ip6tRemoveList'>
+                       <arg type='aa{sv}' name='rule_list' direction='in'/>
+                       <arg type='i' name='error_code' direction='out'/>
+               </method>
                <method name='Ip6tAddRule'>
                        <arg type='a{sv}' name='rules' direction='in'/>
                        <arg type='i' name='error_code' direction='out'/>
index 35e6269..a625c22 100755 (executable)
@@ -503,6 +503,58 @@ int ip6tables_add_rule(ip6tables_rule_s *rule)
        return STC_ERROR_NONE;
 }
 
+int ip6tables_add_rule_list(GSList *rule_list)
+{
+       GSList *list;
+       ip6t_handle_t *handle;
+
+       handle = ip6tc_init(IP6TC_TABLE);
+       if (handle == NULL) {
+               STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno));
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       for (list = rule_list; list; list = list->next) {
+               ip6tables_rule_s *rule = list->data;
+               const char *chain = rule->chain;
+               unsigned char entry[SIZE_TOTAL] = {0, };
+               unsigned char mask[SIZE_TOTAL] = {0, };
+
+               if (!ip6tc_is_chain(chain, handle)) {
+                       STC_LOGE("chain not present [%s]", ip6tc_strerror(errno));
+                       continue;
+               }
+
+               if (__create_entry_data(entry, mask, rule) != 0) {
+                       STC_LOGE("Failed to create entry");
+                       continue;
+               }
+
+               if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
+                       STC_LOGD("Entry already present");
+                       continue;
+               }
+
+               if (!ip6tc_append_entry(chain, (const ip6t_entry_t *)entry, handle)) {
+                       STC_LOGE("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno));
+                       continue;
+               }
+
+               STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name);
+       }
+
+       if (!ip6tc_commit(handle)) {
+               STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno));
+               ip6tc_free(handle);
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       STC_LOGI("Successed to add rule list");
+       ip6tc_free(handle);
+       return STC_ERROR_NONE;
+}
+
+
 int ip6tables_insert_rule(ip6tables_rule_s *rule)
 {
        ip6t_handle_t *handle;
@@ -595,6 +647,52 @@ int ip6tables_remove_rule(ip6tables_rule_s *rule)
        return STC_ERROR_NONE;
 }
 
+int ip6tables_remove_rule_list(GSList *rule_list)
+{
+       GSList *list;
+       ip6t_handle_t *handle;
+
+       handle = ip6tc_init(IP6TC_TABLE);
+       if (handle == NULL) {
+               STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno));
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       for (list = rule_list; list; list = list->next) {
+               ip6tables_rule_s *rule = list->data;
+               const char *chain = rule->chain;
+               unsigned char entry[SIZE_TOTAL] = {0, };
+               unsigned char mask[SIZE_TOTAL] = {0, };
+
+               if (!ip6tc_is_chain(chain, handle)) {
+                       STC_LOGE("chain not present [%s]", ip6tc_strerror(errno));
+                       continue;
+               }
+
+               if (__create_entry_data(entry, mask, rule) != 0) {
+                       STC_LOGE("Failed to create entry");
+                       continue;
+               }
+
+               if (!ip6tc_delete_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) {
+                       STC_LOGE("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno));
+                       continue;
+               }
+
+               STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name);
+       }
+
+       if (!ip6tc_commit(handle)) {
+               STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno));
+               ip6tc_free(handle);
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       STC_LOGI("Successed to remove rule list");
+       ip6tc_free(handle);
+       return STC_ERROR_NONE;
+}
+
 int ip6tables_add_chain(const char *chain)
 {
        ip6t_handle_t *handle;
index 8da2f64..a4ff7f4 100755 (executable)
@@ -103,6 +103,7 @@ typedef struct {
  * @return 0 on success and negative value if error.
  */
 int ip6tables_add_rule(ip6tables_rule_s *rule);
+int ip6tables_add_rule_list(GSList *rule_list);;
 
 /**
  * @desc This function inserts a new ip6tables rule.
@@ -115,6 +116,7 @@ int ip6tables_insert_rule(ip6tables_rule_s *rule);
  * @return 0 on success and negative value if error.
  */
 int ip6tables_remove_rule(ip6tables_rule_s *rule);
+int ip6tables_remove_rule_list(GSList *rule_list);
 
 /**
  * @desc This function adds a new ip6tables chain.
index e43cc0d..999b40d 100755 (executable)
@@ -494,6 +494,57 @@ int iptables_add_rule(iptables_rule_s *rule)
        return STC_ERROR_NONE;
 }
 
+int iptables_add_rule_list(GSList *rule_list)
+{
+       GSList *list;
+       ipt_handle_t *handle;
+
+       handle = iptc_init(IPTC_TABLE);
+       if (handle == NULL) {
+               STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno));
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       for (list = rule_list; list; list = list->next) {
+               iptables_rule_s *rule = list->data;
+               const char *chain = rule->chain;
+               unsigned char entry[SIZE_TOTAL] = {0, };
+               unsigned char mask[SIZE_TOTAL] = {0, };
+
+               if (!iptc_is_chain(chain, handle)) {
+                       STC_LOGE("chain not present [%s]", iptc_strerror(errno));
+                       continue;
+               }
+
+               if (__create_entry_data(entry, mask, rule) != 0) {
+                       STC_LOGE("Failed to create entry");
+                       continue;
+               }
+
+               if (iptc_check_entry(chain, (const ipt_entry_t *)entry, mask, handle)) {
+                       STC_LOGD("Entry already present");
+                       continue;
+               }
+
+               if (!iptc_append_entry(chain, (const ipt_entry_t *)entry, handle)) {
+                       STC_LOGE("iptc_append_entry failed [%s]", iptc_strerror(errno));
+                       continue;
+               }
+
+               STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name);
+       }
+
+       if (!iptc_commit(handle)) {
+               STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno));
+               iptc_free(handle);
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       STC_LOGI("Successed to add rule list");
+       iptc_free(handle);
+       return STC_ERROR_NONE;
+}
+
 int iptables_insert_rule(iptables_rule_s *rule)
 {
        ipt_handle_t *handle;
@@ -586,6 +637,52 @@ int iptables_remove_rule(iptables_rule_s *rule)
        return STC_ERROR_NONE;
 }
 
+int iptables_remove_rule_list(GSList *rule_list)
+{
+       GSList *list;
+       ipt_handle_t *handle;
+
+       handle = iptc_init(IPTC_TABLE);
+       if (handle == NULL) {
+               STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno));
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       for (list = rule_list; list; list = list->next) {
+               iptables_rule_s *rule = list->data;
+               const char *chain = rule->chain;
+               unsigned char entry[SIZE_TOTAL] = {0, };
+               unsigned char mask[SIZE_TOTAL] = {0, };
+
+               if (!iptc_is_chain(chain, handle)) {
+                       STC_LOGE("chain not present [%s]", iptc_strerror(errno));
+                       continue;
+               }
+
+               if (__create_entry_data(entry, mask, rule) != 0) {
+                       STC_LOGE("Failed to create entry");
+                       continue;
+               }
+
+               if (!iptc_delete_entry(chain, (const ipt_entry_t *)entry, mask, handle)) {
+                       STC_LOGE("iptc_delete_entry failed [%s]", iptc_strerror(errno));
+                       continue;
+               }
+
+               STC_LOGD("Delete entry [%s : %s]", rule->chain, rule->nfacct_name);
+       }
+
+       if (!iptc_commit(handle)) {
+               STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno));
+               iptc_free(handle);
+               return STC_ERROR_OPERATION_FAILED;
+       }
+
+       STC_LOGI("Successed to remove rule list");
+       iptc_free(handle);
+       return STC_ERROR_NONE;
+}
+
 int iptables_add_chain(const char *chain)
 {
        ipt_handle_t *handle;
index 58a36cf..5c3e176 100755 (executable)
@@ -103,6 +103,7 @@ typedef struct {
  * @return 0 on success and negative value if error.
  */
 int iptables_add_rule(iptables_rule_s *rule);
+int iptables_add_rule_list(GSList *rule_list);
 
 /**
  * @desc This function inserts a new iptables rule.
@@ -115,6 +116,7 @@ int iptables_insert_rule(iptables_rule_s *rule);
  * @return 0 on success and negative value if error.
  */
 int iptables_remove_rule(iptables_rule_s *rule);
+int iptables_remove_rule_list(GSList *rule_list);
 
 /**
  * @desc This function adds a new iptables chain.
index 01c1537..b966726 100755 (executable)
@@ -133,6 +133,14 @@ static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables)
                         G_CALLBACK(handle_iptables_remove_rule),
                         stc_iptables);
 
+       g_signal_connect(rule, "handle-ipt-add-list",
+                        G_CALLBACK(handle_iptables_add_list),
+                        stc_iptables);
+
+       g_signal_connect(rule, "handle-ipt-remove-list",
+                        G_CALLBACK(handle_iptables_remove_list),
+                        stc_iptables);
+
        g_signal_connect(rule, "handle-ip6t-add-rule",
                         G_CALLBACK(handle_ip6tables_add_rule),
                         stc_iptables);
@@ -145,6 +153,14 @@ static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables)
                         G_CALLBACK(handle_ip6tables_remove_rule),
                         stc_iptables);
 
+       g_signal_connect(rule, "handle-ip6t-add-list",
+                        G_CALLBACK(handle_ip6tables_add_list),
+                        stc_iptables);
+
+       g_signal_connect(rule, "handle-ip6t-remove-list",
+                        G_CALLBACK(handle_ip6tables_remove_list),
+                        stc_iptables);
+
        g_dbus_object_manager_server_export(stc_iptables->obj_mgr,
                                            G_DBUS_OBJECT_SKELETON(object));
        g_object_unref(object);
index 7bb99e2..54902cf 100755 (executable)
@@ -407,8 +407,10 @@ void __stc_extract_6_rule(const char *key, GVariant *value,
        }
 }
 
-static void __free_rule(iptables_rule_s *rule)
+static void __free_rule(gpointer data)
 {
+       iptables_rule_s *rule = (iptables_rule_s *)data;
+
        FREE(rule->chain);
        FREE(rule->ifname);
        FREE(rule->nfacct_name);
@@ -418,8 +420,10 @@ static void __free_rule(iptables_rule_s *rule)
        FREE(rule);
 }
 
-static void __free_6_rule(ip6tables_rule_s *rule)
+static void __free_6_rule(gpointer data)
 {
+       ip6tables_rule_s *rule = (ip6tables_rule_s *)data;
+
        FREE(rule->chain);
        FREE(rule->ifname);
        FREE(rule->nfacct_name);
@@ -709,6 +713,120 @@ gboolean handle_iptables_flush_chain(StcChain *object,
        return TRUE;
 }
 
+gboolean handle_iptables_add_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data)
+{
+       __LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
+       stc_error_e ret = STC_ERROR_NONE;
+       GSList *iptables_list = NULL;
+       GVariant *return_parameters = NULL;
+       struct timespec start, end;
+       time_t sec;
+       long int nsec;
+
+       stc_set_keep_alive(TRUE);
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       g_variant_get(rule_list, "aa{sv}", &iter);
+       while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+               iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1);
+               if (rule != NULL) {
+                       stc_iptables_gdbus_dict_foreach(iter_row,
+                                                       __stc_extract_rule,
+                                                       rule);
+
+                       iptables_list = g_slist_append(iptables_list, rule);
+               }
+               g_variant_iter_free(iter_row);
+       }
+       g_variant_iter_free(iter);
+
+       ret = iptables_add_rule_list(iptables_list);
+
+       g_slist_free_full(iptables_list, __free_rule);
+
+       clock_gettime(CLOCK_MONOTONIC, &end);
+
+       sec = end.tv_sec - start.tv_sec;
+       nsec = end.tv_nsec - start.tv_nsec;
+       if (nsec < 0)
+               nsec += 1000000000;
+
+       STC_LOGD("%s to add list [%3ld.%09ld]s",
+               ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec);
+
+       return_parameters = g_variant_new("(i)", ret);
+
+       STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
+       STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
+
+       __LOG_FUNC_EXIT__;
+       return TRUE;
+}
+
+gboolean handle_iptables_remove_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data)
+{
+       __LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
+       stc_error_e ret = STC_ERROR_NONE;
+       GSList *iptables_list = NULL;
+       GVariant *return_parameters = NULL;
+       struct timespec start, end;
+       time_t sec;
+       long int nsec;
+
+       stc_set_keep_alive(TRUE);
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
+
+       g_variant_get(rule_list, "aa{sv}", &iter);
+       while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+               iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1);
+               if (rule != NULL) {
+                       stc_iptables_gdbus_dict_foreach(iter_row,
+                                                       __stc_extract_rule,
+                                                       rule);
+
+                       iptables_list = g_slist_append(iptables_list, rule);
+               }
+               g_variant_iter_free(iter_row);
+       }
+       g_variant_iter_free(iter);
+
+       ret = iptables_remove_rule_list(iptables_list);
+
+       g_slist_free_full(iptables_list, __free_rule);
+
+       clock_gettime(CLOCK_MONOTONIC, &end);
+
+       sec = end.tv_sec - start.tv_sec;
+       nsec = end.tv_nsec - start.tv_nsec;
+       if (nsec < 0)
+               nsec += 1000000000;
+
+       STC_LOGD("%s to remove list [%3ld.%09ld]s",
+               ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec);
+
+       return_parameters = g_variant_new("(i)", ret);
+
+       STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
+       STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
+
+       __LOG_FUNC_EXIT__;
+       return TRUE;
+}
+
 gboolean handle_ip6tables_add_rule(StcRule *object,
                               GDBusMethodInvocation *invocation,
                               GVariant *rules,
@@ -968,3 +1086,115 @@ gboolean handle_ip6tables_flush_chain(StcChain *object,
        __LOG_FUNC_EXIT__;
        return TRUE;
 }
+
+gboolean handle_ip6tables_add_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data)
+{
+       __LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
+       stc_error_e ret = STC_ERROR_NONE;
+       GSList *iptables_list = NULL;
+       GVariant *return_parameters = NULL;
+       struct timespec start, end;
+       time_t sec;
+       long int nsec;
+
+       stc_set_keep_alive(TRUE);
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       g_variant_get(rule_list, "aa{sv}", &iter);
+       while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+               ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1);
+               if (rule != NULL) {
+                       stc_iptables_gdbus_dict_foreach(iter_row,
+                                                       __stc_extract_6_rule,
+                                                       rule);
+
+                       iptables_list = g_slist_append(iptables_list, rule);
+               }
+               g_variant_iter_free(iter_row);
+       }
+       g_variant_iter_free(iter);
+
+       clock_gettime(CLOCK_MONOTONIC, &end);
+
+       ret = ip6tables_add_rule_list(iptables_list);
+
+       g_slist_free_full(iptables_list, __free_6_rule);
+
+       sec = end.tv_sec - start.tv_sec;
+       nsec = end.tv_nsec - start.tv_nsec;
+       if (nsec < 0)
+               nsec += 1000000000;
+
+       STC_LOGD("%s to add list [%3ld.%09ld]s",
+               ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec);
+
+       return_parameters = g_variant_new("(i)", ret);
+
+       STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
+       STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
+
+       __LOG_FUNC_EXIT__;
+       return TRUE;
+}
+
+gboolean handle_ip6tables_remove_list(StcRule *object,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *rule_list,
+                              void *user_data)
+{
+       __LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
+       stc_error_e ret = STC_ERROR_NONE;
+       GSList *iptables_list = NULL;
+       GVariant *return_parameters = NULL;
+       struct timespec start, end;
+       time_t sec;
+       long int nsec;
+
+       stc_set_keep_alive(TRUE);
+
+       clock_gettime(CLOCK_MONOTONIC, &start);
+
+       g_variant_get(rule_list, "aa{sv}", &iter);
+       while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+               ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1);
+               if (rule != NULL) {
+                       stc_iptables_gdbus_dict_foreach(iter_row,
+                                                       __stc_extract_6_rule,
+                                                       rule);
+
+                       iptables_list = g_slist_append(iptables_list, rule);
+               }
+               g_variant_iter_free(iter_row);
+       }
+       g_variant_iter_free(iter);
+
+       ret = ip6tables_remove_rule_list(iptables_list);
+
+       g_slist_free_full(iptables_list, __free_6_rule);
+
+       clock_gettime(CLOCK_MONOTONIC, &end);
+
+       sec = end.tv_sec - start.tv_sec;
+       nsec = end.tv_nsec - start.tv_nsec;
+       if (nsec < 0)
+               nsec += 1000000000;
+
+       STC_LOGD("%s to add list [%3ld.%09ld]s",
+               ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec);
+
+       return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
+
+       STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
+       STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
+
+       __LOG_FUNC_EXIT__;
+       return TRUE;
+}