Add exclusion rule logic
[platform/core/connectivity/stc-manager.git] / src / monitor / stc-monitor.c
index 50a917f..83d64d0 100755 (executable)
@@ -54,6 +54,8 @@ static nfacct_rule_jump __get_jump_by_intend(struct nfacct_rule *counter)
                return NFACCT_JUMP_ACCEPT;
        else if (counter->intend == NFACCT_BLOCK)
                return NFACCT_JUMP_REJECT;
+       else if (counter->intend == NFACCT_ALLOW)
+               return NFACCT_JUMP_ACCEPT;
 
        return NFACCT_JUMP_UNKNOWN;
 }
@@ -460,20 +462,94 @@ static void __print_rstn(stc_rstn_key_s *rstn_key, stc_rstn_value_s *rstn_value)
 {
        STC_LOGI("rstn info => rstn_id [%llu], "
                 "app_id [%s], classid [%lu], ifname [%s], "
-                "iftype [%d], rst_state [%d], "
+                "iftype [%d], rst_state [%d], rst_type [%d], "
                 "limit [ (%lld) bytes], "
                 "warn_limit [ (%lld) bytes], "
                 "counter [ (%lld) bytes], "
                 "roaming [%d], subscriber_id [%s]",
                 rstn_value->restriction_id,
                 rstn_key->app_id, rstn_value->classid , rstn_key->ifname,
-                rstn_key->iftype, rstn_value->rst_state,
+                rstn_key->iftype, rstn_value->rst_state, rstn_value->rst_type,
                 rstn_value->data_limit,
                 rstn_value->data_warn_limit,
                 rstn_value->data_counter,
                 rstn_key->roaming, rstn_key->subscriber_id);
 }
 
+static void __add_iptables_rule(int64_t classid, nfacct_rule_intend intend,
+                               stc_iface_type_e iftype)
+{
+       char *default_ifname = stc_default_connection_get_ifname();
+       struct nfacct_rule counter;
+       stc_s *stc = stc_get_manager();
+       if (!stc) {
+               g_free(default_ifname); //LCOV_EXCL_LINE
+               return; //LCOV_EXCL_LINE
+       }
+
+       if (!stc->carg) {
+               stc->carg = MALLOC0(counter_arg_s, 1); //LCOV_EXCL_LINE
+               if (stc->carg == NULL) { //LCOV_EXCL_LINE
+                       g_free(default_ifname); //LCOV_EXCL_LINE
+                       return; //LCOV_EXCL_LINE
+               }
+
+               stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE
+       }
+
+       counter.carg = stc->carg;
+       counter.classid = classid;
+       counter.intend = intend;
+       counter.iftype = iftype;
+       g_strlcpy(counter.ifname, default_ifname, MAX_IFACE_LENGTH);
+       g_free(default_ifname);
+
+       /* iptables rule */
+       __add_iptables_in(&counter);
+       __add_iptables_out(&counter);
+
+       /* ip6tables rule */
+       __add_ip6tables_in(&counter);
+       __add_ip6tables_out(&counter);
+}
+
+static void __del_iptables_rule(int64_t classid, nfacct_rule_intend intend,
+                               stc_iface_type_e iftype)
+{
+       char *default_ifname = stc_default_connection_get_ifname();
+       struct nfacct_rule counter;
+       stc_s *stc = stc_get_manager();
+       if (!stc) {
+               g_free(default_ifname); //LCOV_EXCL_LINE
+               return; //LCOV_EXCL_LINE
+       }
+
+       if (!stc->carg) {
+               stc->carg = MALLOC0(counter_arg_s, 1); //LCOV_EXCL_LINE
+               if (stc->carg == NULL) { //LCOV_EXCL_LINE
+                       g_free(default_ifname); //LCOV_EXCL_LINE
+                       return; //LCOV_EXCL_LINE
+               }
+
+               stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE
+       }
+
+       counter.carg = stc->carg;
+       counter.classid = classid;
+       counter.intend = intend;
+       counter.iftype = iftype;
+       g_strlcpy(counter.ifname, default_ifname, MAX_IFACE_LENGTH);
+       g_free(default_ifname);
+
+       /* iptables rule */
+       __del_iptables_in(&counter);
+       __del_iptables_out(&counter);
+
+       /* ip6tables rule */
+       __del_ip6tables_in(&counter);
+       __del_ip6tables_out(&counter);
+}
+
 static void __process_restriction(enum traffic_restriction_type rst_type,
                                  stc_rstn_key_s *rstn_key,
                                  stc_rstn_value_s *rstn_value, void *data)
@@ -531,87 +607,26 @@ static void __process_restriction(enum traffic_restriction_type rst_type,
 
        switch (rst_type) {
        case RST_SET:
-               if (effective_data_limit <= 0) {
-                       char *default_ifname = stc_default_connection_get_ifname();
-                       struct nfacct_rule counter;
-                       stc_s *stc = stc_get_manager();
-                       if (!stc) {
-                               g_free(default_ifname); //LCOV_EXCL_LINE
-                               return; //LCOV_EXCL_LINE
-                       }
-
-                       if (!stc->carg) {
-                               stc->carg = MALLOC0(counter_arg_s, 1); //LCOV_EXCL_LINE
-                               if (stc->carg == NULL) { //LCOV_EXCL_LINE
-                                       g_free(default_ifname); //LCOV_EXCL_LINE
-                                       return; //LCOV_EXCL_LINE
-                               }
-
-                               stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE
-                       }
-
-                       counter.carg = stc->carg;
-                       counter.classid = rstn_value->classid;
-                       counter.intend = NFACCT_BLOCK;
-                       counter.iftype = rstn_key->iftype;
-                       g_strlcpy(counter.ifname, default_ifname,
-                                 MAX_IFACE_LENGTH);
-                       g_free(default_ifname);
-
-                       /* iptables rule */
-                       __add_iptables_in(&counter);
-                       __add_iptables_out(&counter);
-
-                       /* ip6tables rule */
-                       __add_ip6tables_in(&counter);
-                       __add_ip6tables_out(&counter);
-               }
+               if (effective_data_limit <= 0)
+                       __add_iptables_rule(rstn_value->classid, NFACCT_BLOCK,
+                                           rstn_key->iftype);
 
                rstn_value->rst_state = STC_RESTRICTION_ACTIVATED;
                rstn_value->data_limit_reached = FALSE;
                break;
        case RST_EXCLUDE:
-               ;//Do Nothing
+               __add_iptables_rule(rstn_value->classid, NFACCT_ALLOW,
+                                   rstn_key->iftype);
+
+               rstn_value->rst_state = STC_RESTRICTION_ACTIVATED;
+               rstn_value->data_limit_reached = TRUE;
                break;
        case RST_UNSET:
-               {
-                       char *default_ifname = stc_default_connection_get_ifname();
-                       struct nfacct_rule counter;
-                       stc_s *stc = stc_get_manager();
-                       if (!stc) {
-                               g_free(default_ifname); //LCOV_EXCL_LINE
-                               return; //LCOV_EXCL_LINE
-                       }
-
-                       if (!stc->carg) {
-                               stc->carg = MALLOC0(counter_arg_s, 1); //LCOV_EXCL_LINE
-                               if (stc->carg == NULL) { //LCOV_EXCL_LINE
-                                       g_free(default_ifname); //LCOV_EXCL_LINE
-                                       return; //LCOV_EXCL_LINE
-                               }
-
-                               stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE
-                       }
-
-                       counter.carg = stc->carg;
-                       counter.classid = rstn_value->classid;
-                       counter.intend = NFACCT_BLOCK;
-                       counter.iftype = rstn_key->iftype;
-                       g_strlcpy(counter.ifname, default_ifname,
-                                 MAX_IFACE_LENGTH);
-                       g_free(default_ifname);
-
-                       /* iptables rule */
-                       __del_iptables_in(&counter);
-                       __del_iptables_out(&counter);
-
-                       /* ip6tables rule */
-                       __del_ip6tables_in(&counter);
-                       __del_ip6tables_out(&counter);
-
-                       rstn_value->rst_state = STC_RESTRICTION_REMOVED;
-                       rstn_value->data_limit_reached = FALSE;
-               }
+               __del_iptables_rule(rstn_value->classid, rstn_value->rst_type,
+                                   rstn_key->iftype);
+
+               rstn_value->rst_state = STC_RESTRICTION_DEACTIVATED;
+               rstn_value->data_limit_reached = FALSE;
                break;
        default:
                ;//Do Nothing
@@ -636,7 +651,7 @@ static gboolean __remove_rstns_foreach_application(gpointer key,
                goto out;
 
        /* rstn rule is already removed */
-       if (rstn_value->rst_state == STC_RESTRICTION_REMOVED)
+       if (rstn_value->rst_state == STC_RESTRICTION_DEACTIVATED)
                goto out;
 
        /* remove restriction from system */
@@ -1263,7 +1278,7 @@ static gboolean __add_restriction_debug(gpointer key, gpointer value,
        if (rstn_value->rst_state == STC_RESTRICTION_ACTIVATED)
                return FALSE;
 
-       if (rstn_value->rst_state == STC_RESTRICTION_EXCLUDED)
+       if (rstn_value->rst_type == STC_RSTN_TYPE_EXCLUDED)
                __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, data);
        else
                __process_restriction(RST_SET, rstn_key, rstn_value, data);
@@ -1283,7 +1298,7 @@ static gboolean __add_restriction(gpointer key, gpointer value, gpointer data)
        if (rstn_value->rst_state == STC_RESTRICTION_ACTIVATED)
                return FALSE;
 
-       if (rstn_value->rst_state == STC_RESTRICTION_EXCLUDED)
+       if (rstn_value->rst_type == STC_RSTN_TYPE_EXCLUDED)
                __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, data);
        else
                __process_restriction(RST_SET, rstn_key, rstn_value, data);
@@ -1320,34 +1335,36 @@ static stc_error_e __rstn_tree_remove(stc_rstn_key_s *key)
 static stc_error_e __rstn_tree_add(stc_rstn_key_s *key,
                                   stc_rstn_value_s *value, gboolean debug)
 {
+       stc_rstn_key_s *rstn_key;
        stc_rstn_value_s *rstn_value;
 
        ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!");
 
        rstn_value = __rstn_lookup(g_system->rstns, key);
-       if (!rstn_value) {
-               stc_rstn_key_s *rstn_key = MALLOC0(stc_rstn_key_s, 1);
-               if (!rstn_key) {
-                       STC_LOGE("rstn_key allocation failed"); //LCOV_EXCL_LINE
-                       return STC_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
-               }
-
-               rstn_value = MALLOC0(stc_rstn_value_s, 1);
-               if (!rstn_value) {
-                       STC_LOGE("rstn_value allocation failed"); //LCOV_EXCL_LINE
-                       FREE(rstn_key); //LCOV_EXCL_LINE
-                       return STC_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
-               }
+       if (rstn_value)
+               __rstn_tree_remove(key);
 
-               rstn_key->app_id = g_strdup(key->app_id);
-               rstn_key->ifname = g_strdup(key->ifname);
-               rstn_key->subscriber_id = g_strdup(key->subscriber_id);
-               rstn_key->iftype = key->iftype;
-               rstn_key->roaming = key->roaming;
+       rstn_key = MALLOC0(stc_rstn_key_s, 1);
+       if (!rstn_key) {
+               STC_LOGE("rstn_key allocation failed"); //LCOV_EXCL_LINE
+               return STC_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
+       }
 
-               g_tree_insert(g_system->rstns, rstn_key, rstn_value);
+       rstn_value = MALLOC0(stc_rstn_value_s, 1);
+       if (!rstn_value) {
+               STC_LOGE("rstn_value allocation failed"); //LCOV_EXCL_LINE
+               FREE(rstn_key); //LCOV_EXCL_LINE
+               return STC_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
        }
 
+       rstn_key->app_id = g_strdup(key->app_id);
+       rstn_key->ifname = g_strdup(key->ifname);
+       rstn_key->subscriber_id = g_strdup(key->subscriber_id);
+       rstn_key->iftype = key->iftype;
+       rstn_key->roaming = key->roaming;
+
+       g_tree_insert(g_system->rstns, rstn_key, rstn_value);
+
        rstn_value->restriction_id = value->restriction_id;
        rstn_value->rst_state = value->rst_state;
        rstn_value->rst_type = value->rst_type;
@@ -1434,7 +1451,7 @@ static gboolean __add_rstn_foreach_application(gpointer key,
                goto out;
 
        /* add restriction to system */
-       if (rstn_value->rst_state == STC_RESTRICTION_EXCLUDED)
+       if (rstn_value->rst_type == STC_RSTN_TYPE_EXCLUDED)
                __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, NULL);
        else
                __process_restriction(RST_SET, rstn_key, rstn_value, NULL);