Merge "Initialize memory for nfacct rule" into tizen accepted/tizen/unified/20180906.054612 accepted/tizen/unified/20180907.043144 submit/tizen/20180905.125143 submit/tizen/20180907.021206
authorJaehyun Kim <jeik01.kim@samsung.com>
Wed, 5 Sep 2018 11:26:19 +0000 (11:26 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Wed, 5 Sep 2018 11:26:19 +0000 (11:26 +0000)
1  2 
src/monitor/stc-monitor.c

@@@ -31,7 -31,6 +31,7 @@@
  #include "stc-time.h"
  #include "stc-manager-plugin-appstatus.h"
  #include "stc-manager-plugin-exception.h"
 +#include "stc-manager-plugin-tether.h"
  
  #define GRANULARITY 10
  #define MAX_INT_LENGTH 128
@@@ -102,10 -101,6 +102,10 @@@ static nfacct_rule_jump __get_jump_by_i
                return NFACCT_JUMP_REJECT;
        else if (counter->intend == NFACCT_ALLOW)
                return NFACCT_JUMP_ACCEPT;
 +      else if (counter->intend == NFACCT_TETH_BLOCK)
 +              return NFACCT_JUMP_REJECT;
 +      else if (counter->intend == NFACCT_TETH_ALLOW)
 +              return NFACCT_JUMP_ACCEPT;
  
        return NFACCT_JUMP_UNKNOWN;
  }
@@@ -129,7 -124,7 +129,7 @@@ static stc_error_e __add_iptables_tethe
  
        ret = produce_net_rule(counter);
  
 -      g_free(counter->src_ip1);
 +      FREE(counter->src_ip1);
        counter->src_iprange_type = NFACCT_IPRANGE_TYPE_NONE;
        return ret;
  }
@@@ -153,7 -148,7 +153,7 @@@ static stc_error_e __add_iptables_tethe
  
        ret = produce_net_rule(counter);
  
 -      g_free(counter->dst_ip1);
 +      FREE(counter->dst_ip1);
        counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_NONE;
        return ret;
  }
@@@ -177,7 -172,7 +177,7 @@@ static stc_error_e __del_iptables_tethe
  
        ret = produce_net_rule(counter);
  
 -      g_free(counter->src_ip1);
 +      FREE(counter->src_ip1);
        counter->src_iprange_type = NFACCT_IPRANGE_TYPE_NONE;
        return ret;
  }
@@@ -201,7 -196,7 +201,7 @@@ static stc_error_e __del_iptables_tethe
  
        ret = produce_net_rule(counter);
  
 -      g_free(counter->dst_ip1);
 +      FREE(counter->dst_ip1);
        counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_NONE;
        return ret;
  }
@@@ -520,19 -515,16 +520,19 @@@ static gboolean __processes_tree_check_
  }
  //LCOV_EXCL_STOP
  
 -static gboolean __add_application_monitor_for_tethering(gpointer key, gpointer value,
 -                                  gpointer data)
 +static gboolean __add_application_monitor_for_tethering(gpointer key,
 +                                  gpointer value, gpointer data)
  {
        stc_app_value_s *app_value = (stc_app_value_s *)value;
        stc_app_key_s *app_key = (stc_app_key_s *)key;
        default_connection_s *connection = (default_connection_s *)data;
        stc_s *stc = stc_get_manager();
        struct nfacct_rule counter;
 +      char *ipaddr = NULL;
 +      int ret;
  
 -      STC_LOGI("add tether app (%s)", app_key->app_id);
 +      STC_LOGI("add appid(%s) classid(%d)", app_key->app_id,
 +                      app_value->classid);
  
        if (stc == NULL || connection == NULL)
                return FALSE;
        counter.iftype = connection->tether_iface.type;
        g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
  
 -      __add_iptables_tether_in(&counter, app_value->ipaddr);
 -      __add_iptables_tether_out(&counter, app_value->ipaddr);
 +      /* get the ip address of the station based on its mac address */
 +      ret = stc_plugin_tether_get_station_ip(app_value->mac, &ipaddr);
 +      if (ret != STC_ERROR_NONE)
 +              return FALSE;
 +
 +      /* tethering iptables rule */
 +      __add_iptables_tether_in(&counter, ipaddr);
 +      __add_iptables_tether_out(&counter, ipaddr);
  
 +      g_free(ipaddr);
        return FALSE;
  }
  
@@@ -579,11 -564,8 +579,11 @@@ static gboolean __remove_application_mo
        default_connection_s *connection = (default_connection_s *)data;
        stc_s *stc = stc_get_manager();
        struct nfacct_rule counter;
 +      char *ipaddr = NULL;
 +      int ret;
  
 -      STC_LOGI("remove tether app (%s)", app_key->app_id);
 +      STC_LOGI("remove appid(%s) classid(%d)", app_key->app_id,
 +                      app_value->classid);
  
        if (stc == NULL || connection == NULL)
                return FALSE;
        counter.iftype = connection->tether_iface.type;
        g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
  
 -      __del_iptables_tether_in(&counter, app_value->ipaddr);
 -      __del_iptables_tether_out(&counter, app_value->ipaddr);
 +      /* get the ip address of the station based on its mac address */
 +      ret = stc_plugin_tether_get_station_ip(app_value->mac, &ipaddr);
 +      if (ret != STC_ERROR_NONE)
 +              return FALSE;
  
 +      __del_iptables_tether_in(&counter, ipaddr);
 +      __del_iptables_tether_out(&counter, ipaddr);
 +
 +      g_free(ipaddr);
        return FALSE;
  }
  
@@@ -784,6 -760,8 +784,8 @@@ static void __add_iptables_rule(int64_
                stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE
        }
  
+       memset(&counter, 0, sizeof(struct nfacct_rule));
        counter.carg = stc->carg;
        counter.classid = classid;
        counter.intend = intend;
        __add_ip6tables_out(&counter);
  }
  
 +static void __add_tethering_iptables_rule(int64_t classid, gchar *mac,
 +              nfacct_rule_intend intend, stc_iface_type_e iftype)
 +{
 +      default_connection_s *connection = stc_get_default_connection();
 +      struct nfacct_rule counter;
 +      stc_s *stc = stc_get_manager();
 +      char *ipaddr = NULL;
 +      int ret;
 +
 +      if (!stc || !mac)
 +              return;
 +
 +      if (!stc->carg) {
 +              stc->carg = MALLOC0(counter_arg_s, 1);
 +              if (stc->carg == NULL)
 +                      return;
 +
 +              stc->carg->sock = stc_monitor_get_counter_socket();
 +      }
 +
 +      memset(&counter, 0, sizeof(struct nfacct_rule));
 +
 +      counter.carg = stc->carg;
 +      counter.classid = classid;
 +      counter.intend = intend;
 +
 +      if (connection->tether_state != TRUE ||
 +              connection->tether_iface.ifname == NULL)
 +      return;
 +
 +      counter.iftype = connection->tether_iface.type;
 +      g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
 +
 +      /* get connected station ip based on its mac */
 +      ret = stc_plugin_tether_get_station_ip(mac, &ipaddr);
 +      if (ret != STC_ERROR_NONE)
 +              return;
 +
 +      /* tethering iptables rule */
 +      __add_iptables_tether_in(&counter, ipaddr);
 +      __add_iptables_tether_out(&counter, ipaddr);
 +      g_free(ipaddr);
 +}
 +
 +static void __del_tethering_iptables_rule(int64_t classid, gchar *mac,
 +              nfacct_rule_intend intend, stc_iface_type_e iftype)
 +{
 +      default_connection_s *connection = stc_get_default_connection();
 +      struct nfacct_rule counter;
 +      stc_s *stc = stc_get_manager();
 +      char *ipaddr = NULL;
 +      int ret;
 +
 +      if (!stc || !mac)
 +              return;
 +
 +      if (!stc->carg) {
 +              stc->carg = MALLOC0(counter_arg_s, 1);
 +              if (stc->carg == NULL)
 +                      return;
 +
 +              stc->carg->sock = stc_monitor_get_counter_socket();
 +      }
 +
 +      memset(&counter, 0, sizeof(struct nfacct_rule));
 +
 +      counter.carg = stc->carg;
 +      counter.classid = classid;
 +      counter.intend = intend;
 +
 +      if (connection->tether_state != TRUE ||
 +              connection->tether_iface.ifname == NULL)
 +      return;
 +
 +      counter.iftype = connection->tether_iface.type;
 +      g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
 +
 +      /* get connected station ip based on its mac */
 +      ret = stc_plugin_tether_get_station_ip(mac, &ipaddr);
 +      if (ret != STC_ERROR_NONE) {
 +              STC_LOGE("Error: no IP found for station mac(%s)", mac);
 +              return;
 +      }
 +
 +      /* tethering iptables rule */
 +      __del_iptables_tether_in(&counter, ipaddr);
 +      __del_iptables_tether_out(&counter, ipaddr);
 +      g_free(ipaddr);
 +}
 +
  static void __del_iptables_rule(int64_t classid, nfacct_rule_intend intend,
                                stc_iface_type_e iftype)
  {
                stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE
        }
  
+       memset(&counter, 0, sizeof(struct nfacct_rule));
        counter.carg = stc->carg;
        counter.classid = classid;
        counter.intend = intend;
@@@ -986,142 -876,6 +990,142 @@@ static stc_cb_ret_e __statistics_info_c
        return STC_CONTINUE;
  }
  
 +static void __process_tethering_restriction(enum traffic_restriction_type rstn_type,
 +              stc_rstn_key_s *rstn_key, stc_rstn_value_s *rstn_value, void *data)
 +{
 +      default_connection_s *old_connection = (default_connection_s *)data;
 +      default_connection_s *connection = NULL;
 +      char *mac_str = NULL;
 +
 +      if (old_connection != NULL)
 +              connection = old_connection;
 +      else
 +              connection = stc_get_default_connection();
 +
 +      /* in case tethering is not active */
 +      if (connection->tether_state == FALSE)
 +              return;
 +
 +      /* rstn not applicable for this interface */
 +      if (rstn_key->ifname != NULL && g_strcmp0("", rstn_key->ifname) != 0 &&
 +                      (g_strcmp0(connection->tether_iface.ifname, rstn_key->ifname) != 0))
 +              return;
 +
 +      /* in case appid not a tethering app */
 +      if (!g_str_has_suffix(rstn_key->app_id, STC_TETHERING_APP_SUFFIX))
 +              return;
 +
 +      /* Ignore TOTAL_TETHERING,
 +       * Process only station appids */
 +      if (rstn_value->classid == STC_TETHERING_APP_CLASSID)
 +              return;
 +
 +      /* get the station mac based on classid */
 +      stc_plugin_tether_get_station_by_classid(rstn_value->classid, &mac_str);
 +      if (!mac_str) {
 +              STC_LOGE("station not found for classid(%d)", rstn_value->classid);
 +              return;
 +      }
 +
 +      switch (rstn_type) {
 +      case RST_SET:
 +      {
 +              int i;
 +              table_counters_info info;
 +              int64_t effective_limit[STC_RSTN_LIMIT_TYPE_MAX] = { 0, };
 +
 +                      memset(&info, 0, sizeof(table_counters_info));
 +                      rstn_value->limit_exceeded = 0;
 +
 +                      if ((rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
 +                                              rstn_value->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
 +                                      (rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
 +                                       rstn_value->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
 +                                      (rstn_value->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
 +                                       rstn_value->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
 +                                      (rstn_value->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
 +                                       rstn_value->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
 +                                      (rstn_value->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
 +                                       rstn_value->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
 +                              table_counters_get(rstn_value->restriction_id, &info);
 +
 +                              time_t current_time = 0;
 +                              cumulative_data_s stat;
 +                              table_statistics_select_rule rule;
 +
 +                              memset(&stat, 0, sizeof(cumulative_data_s));
 +                              stat.month_start_ts = rstn_value->month_start_ts;
 +                              stat.week_start_ts = g_system->last_week_ts;
 +                              stat.day_start_ts = g_system->last_day_ts;
 +
 +                              memset(&rule, 0, sizeof(table_statistics_select_rule));
 +                              rule.from = rstn_value->month_start_ts;
 +                              time(&current_time);
 +                              rule.to = current_time;
 +                              rule.iftype = rstn_key->iftype;
 +                              rule.granularity = GRANULARITY;
 +
 +                              table_statistics_per_app(rstn_key->app_id, &rule, __statistics_info_cb, &stat);
 +
 +                              rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
 +                              rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
 +                              rstn_value->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter + stat.monthly_stat;
 +                              rstn_value->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter + stat.weekly_stat;
 +                              rstn_value->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter + stat.daily_stat;
 +                      }
 +
 +                      for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
 +                              if (rstn_value->limit[i] >= 0) {
 +                                      effective_limit[i] = rstn_value->limit[i] - rstn_value->counter[i];
 +
 +                                      if (effective_limit[i] < 0)
 +                                              rstn_value->limit_exceeded |= (1 << i);
 +                              }
 +                      }
 +
 +                      STC_LOGD("rstn_id [%llu], datausage [%llu] bytes",
 +                                      rstn_value->restriction_id, info.data_counter);
 +
 +                      if (rstn_value->limit_exceeded != 0 &&
 +                                      rstn_value->limit_exceeded != (1 << STC_RSTN_LIMIT_TYPE_DATA_WARN)) {
 +                              __add_tethering_iptables_rule(rstn_value->classid, mac_str,
 +                                              NFACCT_TETH_BLOCK, rstn_key->iftype);
 +                      }
 +
 +                      rstn_value->rstn_state = STC_RSTN_STATE_ACTIVATED;
 +      }
 +      break;
 +      case RST_EXCLUDE:
 +      {
 +              __add_tethering_iptables_rule(rstn_value->classid, mac_str,
 +                                      NFACCT_TETH_ALLOW, rstn_key->iftype);
 +
 +                      rstn_value->rstn_state = STC_RSTN_STATE_ACTIVATED;
 +                      rstn_value->limit_exceeded = 0;
 +                      rstn_value->limit_notified = 0;
 +      }
 +      break;
 +      case RST_UNSET:
 +      {
 +                      int i;
 +                      __del_tethering_iptables_rule(rstn_value->classid, mac_str,
 +                                      NFACCT_TETH_BLOCK, rstn_key->iftype);
 +
 +                      rstn_value->rstn_state = STC_RSTN_STATE_DEACTIVATED;
 +                      rstn_value->limit_exceeded = 0;
 +                      rstn_value->limit_notified = 0;
 +
 +                      for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++)
 +                              if (rstn_value->limit[i] >= 0)
 +                                      rstn_value->counter[i] = 0;
 +      }
 +      break;
 +      default:
 +                      ;//Do Nothing
 +      }
 +      FREE(mac_str);
 +}
 +
  static void __process_restriction(enum traffic_restriction_type rstn_type,
                                  stc_rstn_key_s *rstn_key,
                                  stc_rstn_value_s *rstn_value, void *data)
        if (rstn_value->classid <= STC_UNKNOWN_CLASSID)
                return;
  
 +      /* Do not proceed for tethering station appid if found here,
 +       * for tethering station apps __process_tethering_restriction() call
 +       * will handle it */
 +      if (g_str_has_suffix(rstn_key->app_id, STC_TETHERING_APP_SUFFIX) &&
 +                      rstn_value->classid != STC_TETHERING_APP_CLASSID)
 +              return;
 +
        switch (rstn_type) {
        case RST_SET:
        {
@@@ -1281,9 -1028,6 +1285,9 @@@ static gboolean __remove_rstns_foreach_
        /* remove restriction from system */
        __process_restriction(RST_UNSET, rstn_key, rstn_value, NULL);
  
 +      /* remove tethering restriction from system*/
 +      __process_tethering_restriction(RST_UNSET, rstn_key, rstn_value, NULL);
 +
        __print_rstn(rstn_key, rstn_value);
  out:
        return FALSE;
@@@ -1385,36 -1129,6 +1389,36 @@@ static stc_error_e __close_and_reopen_c
        return STC_ERROR_NONE;
  }
  
 +static void __action_when_rstn_limit_exceeded_tethering(stc_rstn_key_s *rstn_key,
 +              stc_rstn_value_s *rstn_value, classid_bytes_context_s *context)
 +{
 +      char *mac_str = NULL;
 +      struct nfacct_rule *counter = context->counter;
 +
 +      /* get the station mac based on classid */
 +      stc_plugin_tether_get_station_by_classid(counter->classid, &mac_str);
 +      if (!mac_str) {
 +              STC_LOGE("station not found for classid(%d)", counter->classid);
 +              return;
 +      }
 +
 +      STC_LOGI("station mac %s, classid %u, iftype %u, iotype %d, \
 +                      intend %d, ifname %s, bytes %lld", mac_str,
 +                      counter->classid, counter->iftype, counter->iotype,
 +                      counter->intend, counter->ifname, context->bytes);
 +
 +      /* Block tethering station immediately */
 +      counter->intend = NFACCT_TETH_BLOCK;
 +      __del_tethering_iptables_rule(counter->classid, mac_str,
 +                      NFACCT_TETH_BLOCK, rstn_key->iftype);
 +
 +      __add_tethering_iptables_rule(counter->classid, mac_str,
 +                      NFACCT_TETH_BLOCK, rstn_key->iftype);
 +      counter->intend = NFACCT_TETH_COUNTER;
 +
 +      g_free(mac_str);
 +}
 +
  static void __action_when_rstn_limit_exceeded(stc_rstn_limit_type_e limit_type,
                                                stc_rstn_key_s *rstn_key,
                                                stc_rstn_value_s *rstn_value,
                net_popup_content = "restriction threshold crossed";
                net_popup_type = "restriction_noti";
  
 -              /* block immediately */
 -              context->counter->intend = NFACCT_BLOCK;
 -              __del_iptables_in(context->counter);
 -              __del_iptables_out(context->counter);
 -              __add_iptables_in(context->counter);
 -              __add_iptables_out(context->counter);
 +              /* Apply restriction for tethering apps if app_id is of tethering client
 +               * otherwise do the normal iptables rule */
 +              if (context->counter->intend == NFACCT_TETH_COUNTER) {
  
 -              __del_ip6tables_in(context->counter);
 -              __del_ip6tables_out(context->counter);
 -              __add_ip6tables_in(context->counter);
 -              __add_ip6tables_out(context->counter);
 -              context->counter->intend = NFACCT_COUNTER;
 +                      if (g_str_has_suffix(rstn_key->app_id, STC_TETHERING_APP_SUFFIX) &&
 +                                      rstn_value->classid != STC_TETHERING_APP_CLASSID) {
 +                              __action_when_rstn_limit_exceeded_tethering(rstn_key, rstn_value,
 +                                              context);
 +                      }
 +
 +              } else {
 +                      /* block immediately */
 +                      context->counter->intend = NFACCT_BLOCK;
 +                      __del_iptables_in(context->counter);
 +                      __del_iptables_out(context->counter);
 +                      __add_iptables_in(context->counter);
 +                      __add_iptables_out(context->counter);
 +
 +                      __del_ip6tables_in(context->counter);
 +                      __del_ip6tables_out(context->counter);
 +                      __add_ip6tables_in(context->counter);
 +                      __add_ip6tables_out(context->counter);
 +                      context->counter->intend = NFACCT_COUNTER;
 +              }
  
                rstn_value->limit_exceeded |= (1 << limit_type);
  
@@@ -1904,6 -1606,8 +1908,8 @@@ static gboolean __reset_time_counter_fo
                                                stc_monitor_get_counter_socket();
                                }
  
+                               memset(&counter, 0, sizeof(struct nfacct_rule));
                                counter.carg = stc->carg;
                                counter.classid = rstn_value->classid;
                                counter.intend = NFACCT_BLOCK;
@@@ -2179,7 -1883,6 +2185,7 @@@ static gboolean __remove_restriction(gp
        stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
  
        __process_restriction(RST_UNSET, rstn_key, rstn_value, data);
 +      __process_tethering_restriction(RST_UNSET, rstn_key, rstn_value, data);
        __print_rstn(rstn_key, rstn_value);
        return FALSE;
  }
@@@ -2194,13 -1897,10 +2200,13 @@@ static gboolean __add_restriction_debug
        if (rstn_value->rstn_state == STC_RSTN_STATE_ACTIVATED)
                return FALSE;
  
 -      if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT)
 +      if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) {
                __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, data);
 -      else
 +              __process_tethering_restriction(RST_EXCLUDE, rstn_key, rstn_value, data);
 +      } else {
                __process_restriction(RST_SET, rstn_key, rstn_value, data);
 +              __process_tethering_restriction(RST_SET, rstn_key, rstn_value, data);
 +      }
  
        __print_rstn(rstn_key, rstn_value);
  
@@@ -2217,13 -1917,10 +2223,13 @@@ static gboolean __add_restriction(gpoin
        if (rstn_value->rstn_state == STC_RSTN_STATE_ACTIVATED)
                return FALSE;
  
 -      if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT)
 +      if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) {
                __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, data);
 -      else
 +              __process_tethering_restriction(RST_EXCLUDE, rstn_key, rstn_value, data);
 +      } else {
                __process_restriction(RST_SET, rstn_key, rstn_value, data);
 +              __process_tethering_restriction(RST_SET, rstn_key, rstn_value, data);
 +      }
  
        return FALSE;
  }
@@@ -2280,7 -1977,6 +2286,7 @@@ static stc_error_e __rstn_tree_add(stc_
  
        rstn_key->app_id = g_strdup(key->app_id);
        rstn_key->ifname = g_strdup(key->ifname);
 +      rstn_key->mac = g_strdup(key->mac);
        rstn_key->subscriber_id = g_strdup(key->subscriber_id);
        rstn_key->iftype = key->iftype;
        rstn_key->roaming = key->roaming;
@@@ -2381,13 -2077,10 +2387,13 @@@ static gboolean __add_rstn_foreach_appl
                goto out;
  
        /* add restriction to system */
 -      if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT)
 +      if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) {
                __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, NULL);
 -      else
 +              __process_tethering_restriction(RST_EXCLUDE, rstn_key, rstn_value, NULL);
 +      } else {
                __process_restriction(RST_SET, rstn_key, rstn_value, NULL);
 +              __process_tethering_restriction(RST_SET, rstn_key, rstn_value, NULL);
 +      }
  
        __print_rstn(rstn_key, rstn_value);
  out:
@@@ -2606,7 -2299,7 +2612,7 @@@ API stc_error_e stc_monitor_application
        value->type = app_value.type;
        value->data_usage.in_bytes = app_value.data_usage.in_bytes;
        value->data_usage.out_bytes = app_value.data_usage.out_bytes;
 -      g_strlcpy(value->ipaddr, app_value.ipaddr, IPV4_IPADDRESS_LEN);
 +      g_strlcpy(value->mac, app_value.mac, MAC_ADDRESS_LEN);
  
        value->processes = g_tree_new_full(__processes_tree_key_compare, NULL,
                                           __processes_tree_key_free,
        /* create cgroup and update classid */
        value->classid = get_classid_by_app_id(app_key.app_id, TRUE);
  
 +      /* update classid for tethering station based on its mac address */
 +      if (g_str_has_suffix(app_key.app_id, STC_TETHERING_APP_SUFFIX) &&
 +                              value->classid != STC_TETHERING_APP_CLASSID)
 +              stc_plugin_tether_set_station_classid(value->mac, value->classid);
 +
        g_tree_insert(g_system->apps, key, value);
  
        /* add nfacct rule for this classid */
@@@ -2835,7 -2523,6 +2841,7 @@@ stc_error_e stc_monitor_rstns_tree_add(
  
        key.app_id = g_strdup(info->app_id);
        key.ifname = g_strdup(info->ifname);
 +      key.mac = g_strdup(info->mac);
        key.subscriber_id = g_strdup(info->subscriber_id);
        key.iftype = info->iftype;
        key.roaming = info->roaming;
  
        FREE(key.app_id);
        FREE(key.ifname);
 +      FREE(key.mac);
        FREE(key.subscriber_id);
        return ret;
  }