Merge "Return errors to caller" into tizen_5.5
[platform/core/connectivity/stc-manager.git] / src / helper / helper-nfacct-rule.c
index 24376f3..ff703d3 100755 (executable)
@@ -511,14 +511,33 @@ static stc_error_e exec_iptables_cmd(nfacct_rule_s *rule)
        iptables_rule.d_iprange_type = rule->dst_iprange_type;
 
        /* specify source and destination ip address if any */
-       if (rule->src_ip1)
-               inet_aton(rule->src_ip1, &iptables_rule.s_ip1);
-       if (rule->src_ip2)
-               inet_aton(rule->src_ip2, &iptables_rule.s_ip2);
-       if (rule->dst_ip1)
-               inet_aton(rule->dst_ip1, &iptables_rule.d_ip1);
-       if (rule->dst_ip2)
-               inet_aton(rule->dst_ip2, &iptables_rule.d_ip2);
+       if (rule->src_ip1) {
+               if (!inet_aton(rule->src_ip1, &iptables_rule.s_ip1)) {
+                       ret = STC_ERROR_INVALID_PARAMETER;
+                       goto free;
+               }
+       }
+
+       if (rule->src_ip2) {
+               if (!inet_aton(rule->src_ip2, &iptables_rule.s_ip2)) {
+                       ret = STC_ERROR_INVALID_PARAMETER;
+                       goto free;
+               }
+       }
+
+       if (rule->dst_ip1) {
+               if (!inet_aton(rule->dst_ip1, &iptables_rule.d_ip1)) {
+                       ret = STC_ERROR_INVALID_PARAMETER;
+                       goto free;
+               }
+       }
+
+       if (rule->dst_ip2) {
+               if (!inet_aton(rule->dst_ip2, &iptables_rule.d_ip2)) {
+                       ret = STC_ERROR_INVALID_PARAMETER;
+                       goto free;
+               }
+       }
 
        if (rule->action == NFACCT_ACTION_DELETE) {
                /* delete interface rule */
@@ -528,6 +547,7 @@ static stc_error_e exec_iptables_cmd(nfacct_rule_s *rule)
                ret = iptables_add(&iptables_rule, iptype);
        }
 
+free:
        g_free(iptables_rule.nfacct_name);
        g_free(iptables_rule.ifname);
        g_free(iptables_rule.target);
@@ -830,6 +850,88 @@ API stc_error_e produce_net_rule(nfacct_rule_s *rule)
        return ret;
 }
 
+static stc_error_e append_iptables_cmd(GSList **iptables_list, nfacct_rule_s *rule)
+{
+       iptables_rule_s *iptables_rule = NULL;
+
+       iptables_rule = MALLOC0(iptables_rule_s, 1);
+       if (!iptables_rule)
+               return STC_ERROR_OUT_OF_MEMORY;
+
+       iptables_rule->nfacct_name = g_strdup(rule->name);
+       iptables_rule->ifname = g_strdup(rule->ifname);
+       iptables_rule->target = g_strdup(get_iptables_jump(rule->jump));
+       iptables_rule->chain = g_strdup(get_iptables_chain(rule->classid,
+                               rule->iotype, rule->app_state, rule->intend));
+       if (rule->classid < STC_RESERVED_CLASSID_MAX)
+               iptables_rule->classid = STC_UNKNOWN_CLASSID;
+       else
+               iptables_rule->classid = rule->classid;
+       iptables_rule->direction = (rule->iotype & NFACCT_COUNTER_IN) ?
+                                       IPTABLES_DIRECTION_IN : IPTABLES_DIRECTION_OUT;
+
+       *iptables_list = g_slist_append(*iptables_list, iptables_rule);
+
+       return STC_ERROR_NONE;
+}
+
+static void iptables_list_free(gpointer value)
+{
+       iptables_rule_s *iptables_rule = (iptables_rule_s *)value;
+
+       g_free(iptables_rule->chain);
+       g_free(iptables_rule->nfacct_name);
+       g_free(iptables_rule->ifname);
+       g_free(iptables_rule->target);
+       g_free(iptables_rule);
+}
+
+API stc_error_e produce_net_list(GSList *rule_list,
+               nfacct_rule_iptype iptype, nfacct_rule_action action)
+{
+       GSList *list = NULL;
+       GSList *iptables_list = NULL;
+       stc_error_e ret = STC_ERROR_NONE;
+
+       for (list = rule_list; list; list = list->next) {
+               nfacct_rule_s *rule = list->data;
+
+               if (rule->action == NFACCT_ACTION_APPEND &&
+                       rule->intend == NFACCT_WARN &&
+                       !rule->send_limit && !rule->rcv_limit)
+                       continue;
+
+               generate_counter_name(rule);
+               if (rule->action != NFACCT_ACTION_DELETE) {
+                       ret = nfacct_send_del(rule);
+                       if (ret != STC_ERROR_NONE)
+                               continue;
+
+                       ret = nfacct_send_new(rule);
+                       if (ret != STC_ERROR_NONE)
+                               continue;
+               }
+
+               append_iptables_cmd(&iptables_list, rule);
+       }
+
+       if (action == NFACCT_ACTION_INSERT ||
+               action == NFACCT_ACTION_APPEND)
+               ret = iptables_add_list(iptables_list, iptype);
+       else if (action == NFACCT_ACTION_DELETE)
+               ret = iptables_remove_list(iptables_list, iptype);
+
+       for (list = rule_list; list; list = list->next) {
+               nfacct_rule_s *rule = list->data;
+
+               if (rule->action == NFACCT_ACTION_DELETE)
+                       nfacct_send_del(rule);
+       }
+
+       g_slist_free_full(iptables_list, iptables_list_free);
+       return ret;
+}
+
 void generate_counter_name(nfacct_rule_s *counter)
 {
        char warn_symbol = 'c';