*/
enum stc_reserved_classid {
STC_UNKNOWN_CLASSID,
- STC_ALL_APP_CLASSID, /**< kernel expects 1 for
- handling restriction for all
- applications */
- STC_TETHERING_APP_CLASSID, /**< it uses in user space logic
- for counting tethering traffic */
- STC_FOREGROUND_APP_CLASSID, /* it will used for special cgroup,
- blocked cgroup */
- STC_BACKGROUND_APP_CLASSID,
- STC_TOTAL_DATACALL_CLASSID,
- STC_TOTAL_WIFI_CLASSID,
+ STC_ALL_APP_CLASSID, /**< kernel expects 1 for handling restriction for all applications */
+ STC_TETHERING_APP_CLASSID, /**< it uses in user space logic for counting tethering traffic */
+ STC_FOREGROUND_APP_CLASSID, /**< it will used for special cgroup, blocked cgroup */
+ STC_BACKGROUND_APP_CLASSID, /**< background data monitoring */
+ STC_TOTAL_DATACALL_CLASSID, /**< Cellular data monitoring */
+ STC_TOTAL_WIFI_CLASSID, /**< Wi-Fi data monitoring */
STC_TOTAL_BLUETOOTH_CLASSID,
+ STC_TOTAL_IPV4_CLASSID, /**< IPV4 data monitoring */
+ STC_TOTAL_IPV6_CLASSID, /**< IPV6 data monitoring */
STC_NETWORK_RESTRICTION_APP_CLASSID,
STC_RESERVED_CLASSID_MAX,
};
#define STC_TOTAL_DATACALL "TOTAL_DATACALL"
#define STC_TOTAL_WIFI "TOTAL_WIFI"
#define STC_TOTAL_BLUETOOTH "TOTAL_BLUETOOTH"
+#define STC_TOTAL_IPV4 "TOTAL_IPV4"
+#define STC_TOTAL_IPV6 "TOTAL_IPV6"
typedef enum {
STC_CANCEL = 0, /**< cancel */
STC_IFACE_WIFI, /**< wifi data */
STC_IFACE_WIRED, /**< wired interface */
STC_IFACE_BLUETOOTH, /**< bluetooth interface */
+ STC_IFACE_IPV4, /**< ipv4 interface */
+ STC_IFACE_IPV6, /**< ipv6 interface */
STC_IFACE_ALL, /**< enumerate all network interface types */
STC_IFACE_LAST_ELEM
} stc_iface_type_e;
Name: stc-manager
Summary: STC(Smart Traffic Control) manager
-Version: 0.0.25
+Version: 0.0.26
Release: 0
Group: Network & Connectivity/Other
License: Apache-2.0
"ifname, imsi, ground from statistics " \
" where (time_stamp between ? and ?) and binpath != 'TOTAL_DATACALL' " \
"and binpath != 'TOTAL_WIFI' and binpath != 'TOTAL_BLUETOOTH' " \
+ "and binpath != 'TOTAL_IPV4' and binpath != 'TOTAL_IPV6' " \
"group by iftype, ifname, imsi, hw_net_protocol_type, is_roaming " \
"order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \
"is_roaming"
#define MAX_PATH_LENGTH 512
-static int read_uint(FILE *handler, uint32_t *out)
-{
- return fscanf(handler, "%u", out);
-}
-
-static int write_uint(FILE *handler, uint32_t number)
-{
- _cleanup_free_ char *digit_buf = NULL;
- int ret;
-
- ret = asprintf(&digit_buf, "%u\n", number);
- ret_value_errno_msg_if(ret < 0, -ENOMEM, "asprintf failed\n");
-
- ret = fputs(digit_buf, handler);
- ret_value_errno_msg_if(ret == EOF, errno ? -errno : -EIO,
- "Fail to write file");
-
- return 0;
-}
-
static bool cgroup_is_exists(const char *cgroup_full_path)
{
struct stat stat_buf;
return STC_ERROR_NONE;
}
-/* FIXME: tasks is not removed from tasks list */
-int cgroup_remove_pid(const char *cgroup_subsystem, const char *cgroup_name,
- const int pid)
-{
- char cgroup_tasks_file_path[MAX_PATH_LENGTH];
- FILE *handler = 0;
- guint i = 0;
- pid_t pid_for_read = 0;
- GArray *pids = NULL;
- guint pid_count = 0;;
-
- snprintf(cgroup_tasks_file_path, sizeof(cgroup_tasks_file_path),
- "%s/%s/tasks", cgroup_subsystem, cgroup_name);
-
- handler = fopen(cgroup_tasks_file_path, "r");
- if (!handler) {
- STC_LOGE("Read file open failed");
- return -1;
- }
-
- pids = g_array_new(FALSE, FALSE, sizeof(pid_t));
-
- while (read_uint(handler, (uint32_t *)&pid_for_read) >= 0) {
- if (pid_for_read != pid) {
- pids = g_array_append_val(pids, pid_for_read);
- ++pid_count;
- }
- }
-
- fclose(handler);
-
- handler = fopen(cgroup_tasks_file_path, "w");
- if (!handler) {
- STC_LOGE("Write file open failed");
- return -1;
- }
-
- for (i = 0; i < pid_count; i++)
- write_uint(handler, g_array_index(pids, pid_t, i));
-
- fclose(handler);
- g_array_free(pids, TRUE);
- return 0;
-}
-
int cgroup_set_release_agent(const char *cgroup_subsys,
const char *release_agent)
{
int cgroup_get_pids(const char *name, GArray **pids);
/**
- * @desc remove PID from a certain cgroup tasks file.
- * @return 0 if pid removed
- */
-int cgroup_remove_pid(const char *cgroup_subsystem, const char *cgroup_name,
- const int pid);
-
-/**
* @desc initializes cgroups.
*/
void cgroup_init(void);
static uint32_t __produce_classid(check_classid_used_cb check_classid_cb)
{
uint32_t classid = STC_RESERVED_CLASSID_MAX;
- int classid_test_count = 0;
int ret = fread_uint(CUR_CLASSID_PATH, &classid);
if (ret < 0)
STC_LOGI("Can not read current classid");
+
classid += 1;
- if (check_classid_cb)
+
+ if (check_classid_cb) {
+ int classid_test_count = 0;
for (classid_test_count = 0; classid_test_count < INT32_MAX;
++classid) {
if (!check_classid_cb(classid))
break;
}
+ }
ret = fwrite_uint(CUR_CLASSID_PATH, ++classid);
if (ret < 0)
const char *path_to_net_cgroup_dir = NULL;
if (app_id == NULL) {
- STC_LOGE("app_id must be not empty");
+ STC_LOGE("app_id must be not empty");
return STC_UNKNOWN_CLASSID;
}
if (!strcmp(app_id, STC_TOTAL_BLUETOOTH))
return STC_TOTAL_BLUETOOTH_CLASSID;
+ if (!strcmp(app_id, STC_TOTAL_IPV4))
+ return STC_TOTAL_IPV4_CLASSID;
+
+ if (!strcmp(app_id, STC_TOTAL_IPV6))
+ return STC_TOTAL_IPV6_CLASSID;
+
if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
else
#define RULE_APP_OUT "%s -w %s OUTPUT -o %s -m cgroup --cgroup %u %s %s"
#define RULE_APP_IN "%s -w %s INPUT -i %s -m cgroup --cgroup %u %s %s"
-
/* iptables -w [I/A/D] [OUTPUT/FORWARD/INPUT] -o/-i iface -m nfacct --nfacct-name name -j ACCEPT/REJECT */
#define RULE_IFACE_OUT "%s -w %s %s -o %s %s %s"
#define RULE_IFACE_IN "%s -w %s %s -i %s %s %s"
-
#define NFNL_SUBSYS_ACCT 7
#define BUF_SIZE_FOR_ERR 100
{
int status;
pid_t ret_pid;
- char buf[BUF_SIZE_FOR_ERR] = { 0 };
if (!pid || pid == -1) {
STC_LOGD("no need to wait");
}
ret_pid = waitpid(pid, &status, 0);
- if (ret_pid < 0)
+ if (ret_pid < 0) {
+ char buf[BUF_SIZE_FOR_ERR] = { 0 };
STC_LOGD("can't wait for a pid %d %d %s", pid, status,
strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
+ }
}
static char* get_cmd_pos(const char *cmd_buf)
char *args[args_number + 2];
int ret;
char *save_ptr = NULL;
- char buf[BUF_SIZE_FOR_ERR] = { 0 };
STC_LOGD("executing iptables cmd %s in forked process",
cmd_buf);
args[i] = NULL;
ret = execv(cmd, args);
- if (ret)
+ if (ret) {
+ char buf[BUF_SIZE_FOR_ERR] = { 0 };
STC_LOGE("Can't execute %s: %s",
cmd_buf, strerror_r(errno, buf,
BUF_SIZE_FOR_ERR));
+ }
exit(ret);
}
char *args[args_number + 2];
int ret;
char *save_ptr = NULL;
- char buf[BUF_SIZE_FOR_ERR] = { 0 };
STC_LOGD("executing ip6tables cmd %s in forked process",
cmd_buf);
args[i] = NULL;
ret = execv(cmd, args);
- if (ret)
+ if (ret) {
+ char buf[BUF_SIZE_FOR_ERR] = { 0 };
STC_LOGE("Can't execute %s: %s",
- cmd_buf, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
+ cmd_buf, strerror_r(errno, buf,
+ BUF_SIZE_FOR_ERR));
+ }
exit(ret);
}
static stc_error_e exec_iface_cmd(const char *pattern, const char *cmd,
const char *chain, const char *nfacct,
const char *jump, char *iftype_name,
- pid_t *pid)
+ pid_t *pid, nfacct_rule_iptype iptype)
{
char block_buf[MAX_PATH_LENGTH];
int ret;
+ const char *iptables_type = IPTABLES;
ret_value_msg_if(iftype_name == NULL, STC_ERROR_FAIL,
"Invalid network interface name argument");
- /* iptables rule */
- ret = snprintf(block_buf, sizeof(block_buf), pattern, IPTABLES, cmd, chain,
- iftype_name, nfacct, jump);
- ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
- "Not enough buffer");
- exec_iptables_cmd(block_buf, pid);
- wait_for_rule_cmd(*pid);
+ if (iptype == NFACCT_TYPE_IPV6)
+ iptables_type = IP6TABLES;
- /* ip6tables rule */
- ret = snprintf(block_buf, sizeof(block_buf), pattern, IP6TABLES, cmd, chain,
- iftype_name, nfacct, jump);
+ ret = snprintf(block_buf, sizeof(block_buf), pattern, iptables_type,
+ cmd, chain, iftype_name, nfacct, jump);
ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
"Not enough buffer");
- ret = exec_ip6tables_cmd(block_buf, pid);
+
+ if (iptype == NFACCT_TYPE_IPV6)
+ exec_ip6tables_cmd(block_buf, pid);
+ else
+ exec_iptables_cmd(block_buf, pid);
+
wait_for_rule_cmd(*pid);
- return ret;
+ return STC_ERROR_NONE;
}
static stc_error_e exec_app_cmd(const char *pattern, const char *cmd,
const char *nfacct, const char *jump,
const uint32_t classid, char *iftype_name,
- pid_t *pid)
+ pid_t *pid, nfacct_rule_iptype iptype)
{
char block_buf[MAX_PATH_LENGTH];
int ret;
+ const char *iptables_type = IPTABLES;
+
ret_value_msg_if(iftype_name == NULL, STC_ERROR_FAIL,
"Invalid network interface name argument");
- /* iptables rules */
- ret = snprintf(block_buf, sizeof(block_buf), pattern, IPTABLES, cmd,
- iftype_name, classid, nfacct, jump);
- ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
- "Not enough buffer");
- exec_iptables_cmd(block_buf, pid);
- wait_for_rule_cmd(*pid);
+ if (iptype == NFACCT_TYPE_IPV6)
+ iptables_type = IP6TABLES;
- /* ip6tables rules */
- ret = snprintf(block_buf, sizeof(block_buf), pattern, IP6TABLES, cmd,
- iftype_name, classid, nfacct, jump);
+ ret = snprintf(block_buf, sizeof(block_buf), pattern, iptables_type,
+ cmd, iftype_name, classid, nfacct, jump);
ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
"Not enough buffer");
- ret = exec_ip6tables_cmd(block_buf, pid);
+
+ if (iptype == NFACCT_TYPE_IPV6)
+ exec_ip6tables_cmd(block_buf, pid);
+ else
+ exec_iptables_cmd(block_buf, pid);
+
wait_for_rule_cmd(*pid);
- return ret;
+ return STC_ERROR_NONE;
}
static char *get_iptables_cmd(const nfacct_rule_action action)
return "";
}
-static stc_error_e produce_app_rule(nfacct_rule_s *rule,
- const int64_t send_limit,
- const int64_t rcv_limit,
- const nfacct_rule_action action,
- const nfacct_rule_jump jump,
- const nfacct_rule_direction iotype)
+static stc_error_e produce_app_rule(nfacct_rule_s *rule)
{
- char *set_cmd = get_iptables_cmd(action);
- char *jump_cmd = get_iptables_jump(jump);
+ if (rule == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ char *set_cmd = get_iptables_cmd(rule->action);
+ char *jump_cmd = get_iptables_jump(rule->jump);
char nfacct_buf[sizeof(NFACCT_NAME_MOD) +
3*MAX_DEC_SIZE(int) + 4];
stc_error_e ret = STC_ERROR_NONE;
pid_t pid = 0;
/* income part */
- if (iotype & NFACCT_COUNTER_IN) {
- rule->quota = rcv_limit;
+ if (rule->iotype & NFACCT_COUNTER_IN) {
+ rule->quota = rule->rcv_limit;
rule->iotype = NFACCT_COUNTER_IN;
generate_counter_name(rule);
/* to support quated counter we need nfacct,
* don't use it in case of just block without a limit
* iow, send_limit = 0 and rcv_limit 0 */
- if (action != NFACCT_ACTION_DELETE) {
+ if (rule->action != NFACCT_ACTION_DELETE) {
ret = nfacct_send_del(rule);
ret_value_msg_if(ret != STC_ERROR_NONE, ret,
"can't del quota counter");
ret = exec_app_cmd(RULE_APP_IN, set_cmd, nfacct_buf, jump_cmd,
rule->classid, choose_iftype_name(rule),
- &pid);
+ &pid, rule->iptype);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set conditional block for ingress"
" traffic, for classid %u, cmd %s, j %s",
rule->classid, set_cmd, jump_cmd);
/* remove in any case */
- if (action == NFACCT_ACTION_DELETE) {
+ if (rule->action == NFACCT_ACTION_DELETE) {
/* TODO here and everywhere should be not just a del,
* here should be get counted value and than
* set new counter with that value, but it's minor issue,
}
}
- if (iotype & NFACCT_COUNTER_OUT) {
+ if (rule->iotype & NFACCT_COUNTER_OUT) {
/* outcome part */
rule->iotype = NFACCT_COUNTER_OUT;
- rule->quota = send_limit;
+ rule->quota = rule->send_limit;
generate_counter_name(rule);
- if (action != NFACCT_ACTION_DELETE) {
+ if (rule->action != NFACCT_ACTION_DELETE) {
ret = nfacct_send_del(rule);
ret_value_msg_if(ret != STC_ERROR_NONE, ret,
"can't del quota counter");
ret = exec_app_cmd(RULE_APP_OUT, set_cmd, nfacct_buf, jump_cmd,
rule->classid, choose_iftype_name(rule),
- &pid);
+ &pid, rule->iptype);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set conditional block for engress"
" traffic, for classid %u, cmd %s, j %s",
rule->classid, set_cmd, jump_cmd);
- if (action == NFACCT_ACTION_DELETE) {
+ if (rule->action == NFACCT_ACTION_DELETE) {
rule->iptables_rule = nfacct_send_del;
/* not effective, it's better to replace
* set_finalize_flag by set_property,
return STC_ERROR_NONE;
}
-static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
- const int64_t send_limit,
- const int64_t rcv_limit,
- const nfacct_rule_action action,
- const nfacct_rule_jump jump,
- const nfacct_rule_direction iotype)
+static stc_error_e produce_iface_rule(nfacct_rule_s *rule)
{
- char *set_cmd = get_iptables_cmd(action);
- char *jump_cmd = get_iptables_jump(jump);
+ if (rule == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ char *set_cmd = get_iptables_cmd(rule->action);
+ char *jump_cmd = get_iptables_jump(rule->jump);
char nfacct_buf[sizeof(NFACCT_NAME_MOD) +
3*MAX_DEC_SIZE(int) + 4];
stc_error_e ret;
pid_t pid = 0;
- if (iotype & NFACCT_COUNTER_IN) {
+ if (rule->iotype & NFACCT_COUNTER_IN) {
/* income part */
rule->iotype = NFACCT_COUNTER_IN;
- rule->quota = rcv_limit;
+ rule->quota = rule->rcv_limit;
generate_counter_name(rule);
- if (action != NFACCT_ACTION_DELETE) {
+ if (rule->action != NFACCT_ACTION_DELETE) {
/* send delete comman in case of creation,
* because nfacct doesn't reset value for nfacct quota
* in case of quota existing */
ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd,
get_iptables_chain(rule->iotype),
nfacct_buf, jump_cmd,
- choose_iftype_name(rule), &pid);
+ choose_iftype_name(rule), &pid,
+ rule->iptype);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set conditional block for ingress"
" traffic, for iftype %d, cmd %s, j %s",
/* RULE_IFACE_OUT is not a misprint here */
ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd,
FORWARD_RULE, nfacct_buf, jump_cmd,
- choose_iftype_name(rule), &pid);
+ choose_iftype_name(rule), &pid,
+ rule->iptype);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set forward rule for ingress "
"traffic, for iftype %d, cmd %s, j %s",
}
/* tethering */
- if (action == NFACCT_ACTION_DELETE) {
+ if (rule->action == NFACCT_ACTION_DELETE) {
rule->iptables_rule = nfacct_send_del;
set_finalize_flag(rule);
nfacct_send_get(rule);
}
}
- if (iotype & NFACCT_COUNTER_OUT) {
+ if (rule->iotype & NFACCT_COUNTER_OUT) {
/* outcome part */
rule->iotype = NFACCT_COUNTER_OUT;
- rule->quota = send_limit;
+ rule->quota = rule->send_limit;
generate_counter_name(rule);
- if (action != NFACCT_ACTION_DELETE) {
+ if (rule->action != NFACCT_ACTION_DELETE) {
/* send delete comman in case of creation,
* because nfacct doesn't reset value for nfacct quota
* in case of quota existing */
ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd, OUT_RULE,
nfacct_buf, jump_cmd,
- choose_iftype_name(rule), &pid);
+ choose_iftype_name(rule), &pid,
+ rule->iptype);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set conditional block for "
"engress traffic, for iftype %d, cmd %s, j %s",
rule->intend == NFACCT_BLOCK) {
ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd,
FORWARD_RULE, nfacct_buf, jump_cmd,
- choose_iftype_name(rule), &pid);
+ choose_iftype_name(rule), &pid,
+ rule->iptype);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set forward rule for engress "
"traffic, for iftype %d, cmd %s, j %s",
}
/* tethering */
- if (action == NFACCT_ACTION_DELETE) {
+ if (rule->action == NFACCT_ACTION_DELETE) {
rule->iptables_rule = nfacct_send_del;
set_finalize_flag(rule);
nfacct_send_get(rule);
return STC_ERROR_NONE;
}
-stc_error_e produce_net_rule(nfacct_rule_s *rule,
- const int64_t send_limit,
- const int64_t rcv_limit,
- const nfacct_rule_action action,
- const nfacct_rule_jump jump,
- const nfacct_rule_direction iotype)
+stc_error_e produce_net_rule(nfacct_rule_s *rule)
{
stc_error_e ret = STC_ERROR_NONE;
- if (action == NFACCT_ACTION_APPEND && rule->intend == NFACCT_WARN
- && !send_limit && !rcv_limit)
+ if (rule == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ if (rule->action == NFACCT_ACTION_APPEND &&
+ rule->intend == NFACCT_WARN &&
+ !rule->send_limit && !rule->rcv_limit)
return STC_ERROR_NONE;
if (rule->classid != STC_ALL_APP_CLASSID &&
rule->classid != STC_TETHERING_APP_CLASSID &&
rule->classid != STC_TOTAL_DATACALL_CLASSID &&
rule->classid != STC_TOTAL_WIFI_CLASSID &&
- rule->classid != STC_TOTAL_BLUETOOTH_CLASSID)
- ret = produce_app_rule(rule, send_limit,
- rcv_limit, action, jump, iotype);
+ rule->classid != STC_TOTAL_BLUETOOTH_CLASSID &&
+ rule->classid != STC_TOTAL_IPV4_CLASSID &&
+ rule->classid != STC_TOTAL_IPV6_CLASSID)
+ ret = produce_app_rule(rule);
else
- ret = produce_iface_rule(rule, send_limit, rcv_limit,
- action, jump, iotype);
+ ret = produce_iface_rule(rule);
return ret;
}
NFACCT_RULE_LAST_ELEM,
} nfacct_rule_intend;
+typedef enum {
+ NFACCT_TYPE_UNKNOWN,
+ NFACCT_TYPE_IPV4,
+ NFACCT_TYPE_IPV6,
+ NFACCT_TYPE_LAST_ELEM
+} nfacct_rule_iptype;
+
enum nfnl_acct_flags {
NFACCT_F_QUOTA_PKTS = (1 << 0),
NFACCT_F_QUOTA_BYTES = (1 << 1),
pid_t pid;
uint32_t classid;
stc_iface_type_e iftype;
+ nfacct_rule_action action;
nfacct_rule_direction iotype;
nfacct_rule_intend intend;
+ nfacct_rule_jump jump; /* in most cases jump is evalutation based on intend, but not always */
+ stc_restriction_state_e rst_state;
+ nfacct_rule_iptype iptype;
+
struct counter_arg *carg;
stc_error_e(*iptables_rule)(struct nfacct_rule *counter);
int64_t quota;
int quota_id;
stc_roaming_type_e roaming;
- stc_restriction_state_e rst_state;
- /**
- * in most cases jump is evalutation based
- * on intend, but not always
- */
- nfacct_rule_jump jump;
+ int64_t send_limit;
+ int64_t rcv_limit;
};
typedef struct nfacct_rule nfacct_rule_s;
bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *counter);
stc_error_e nfacct_send_get_all(struct counter_arg *carg);
-stc_error_e nfacct_send_get_counters(struct counter_arg *carg,
- const char *name);
-stc_error_e nfacct_send_get(nfacct_rule_s *rule);
-stc_error_e nfacct_send_del(nfacct_rule_s *counter);
-
-stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *pid);
-stc_error_e produce_net_rule(nfacct_rule_s *rule,
- const int64_t send_limit,
- const int64_t rcv_limit,
- const nfacct_rule_action action,
- const nfacct_rule_jump jump,
- const nfacct_rule_direction iotype);
+stc_error_e produce_net_rule(nfacct_rule_s *rule);
netlink_serialization_command *
netlink_create_command(struct netlink_serialization_params *params);
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @file restriction-helper.c
- * @desc Helper restriction functions
- */
-
-#include "stc-manager.h"
-#include "stc-restriction.h"
-#include "transmission.h"
-
-stc_restriction_state_e
-convert_to_restriction_state(const enum traffic_restriction_type rst_type)
-{
- switch (rst_type) {
- case RST_SET:
- return STC_RESTRICTION_ACTIVATED;
- case RST_UNSET:
- return STC_RESTRICTION_REMOVED;
- case RST_EXCLUDE:
- return STC_RESTRICTION_EXCLUDED;
- default:
- return STC_RESTRICTION_UNKNOWN;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file helper-restriction.h
- * @desc Helper restriction functions
- */
-
-#ifndef __STC_HELPER_RESTRICTION_H__
-#define __STC_HELPER_RESTRICTION_H__
-
-#include "stc-manager.h"
-#include "stc-restriction.h"
-#include "transmission.h"
-
-stc_restriction_state_e
-convert_to_restriction_state(const enum traffic_restriction_type rst_type);
-
-#endif /* __STC_HELPER_RESTRICTION_H__ */
static stc_error_e __add_iptables_in(struct nfacct_rule *counter)
{
- return produce_net_rule(counter, 0, 0,
- NFACCT_ACTION_INSERT, __get_jump_by_intend(counter),
- NFACCT_COUNTER_IN);
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_INSERT;
+ counter->iotype = NFACCT_COUNTER_IN;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV4;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
}
static stc_error_e __add_iptables_out(struct nfacct_rule *counter)
{
- return produce_net_rule(counter, 0, 0,
- NFACCT_ACTION_INSERT, __get_jump_by_intend(counter),
- NFACCT_COUNTER_OUT);
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_INSERT;
+ counter->iotype = NFACCT_COUNTER_OUT;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV4;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
}
static stc_error_e __del_iptables_in(struct nfacct_rule *counter)
{
- return produce_net_rule(counter, 0, 0,
- NFACCT_ACTION_DELETE, __get_jump_by_intend(counter),
- NFACCT_COUNTER_IN);
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_DELETE;
+ counter->iotype = NFACCT_COUNTER_IN;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV4;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
}
static stc_error_e __del_iptables_out(struct nfacct_rule *counter)
{
- return produce_net_rule(counter, 0, 0,
- NFACCT_ACTION_DELETE, __get_jump_by_intend(counter),
- NFACCT_COUNTER_OUT);
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_DELETE;
+ counter->iotype = NFACCT_COUNTER_OUT;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV4;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
+}
+
+static stc_error_e __add_ip6tables_in(struct nfacct_rule *counter)
+{
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_INSERT;
+ counter->iotype = NFACCT_COUNTER_IN;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV6;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
+}
+
+static stc_error_e __add_ip6tables_out(struct nfacct_rule *counter)
+{
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_INSERT;
+ counter->iotype = NFACCT_COUNTER_OUT;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV6;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
+}
+
+static stc_error_e __del_ip6tables_in(struct nfacct_rule *counter)
+{
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_DELETE;
+ counter->iotype = NFACCT_COUNTER_IN;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV6;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
+}
+
+static stc_error_e __del_ip6tables_out(struct nfacct_rule *counter)
+{
+ if (counter == NULL)
+ return STC_ERROR_INVALID_PARAMETER;
+
+ counter->action = NFACCT_ACTION_DELETE;
+ counter->iotype = NFACCT_COUNTER_OUT;
+ counter->jump = __get_jump_by_intend(counter);
+ counter->iptype = NFACCT_TYPE_IPV6;
+ counter->send_limit = 0;
+ counter->rcv_limit = 0;
+
+ return produce_net_rule(counter);
}
static int __processes_tree_key_compare(gconstpointer a, gconstpointer b,
stc_s *stc = stc_get_manager();
if (app_value->classid == STC_TOTAL_DATACALL_CLASSID ||
- app_value->classid == STC_TOTAL_WIFI_CLASSID ||
- app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
+ app_value->classid == STC_TOTAL_WIFI_CLASSID ||
+ app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
return FALSE;
if (stc && connection && connection->ifname) {
counter.iftype = connection->type;
g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
- __add_iptables_in(&counter);
- __add_iptables_out(&counter);
+ if (app_value->classid == STC_TOTAL_IPV4_CLASSID) {
+ __add_iptables_in(&counter);
+ __add_iptables_out(&counter);
+ } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) {
+ __add_ip6tables_in(&counter);
+ __add_ip6tables_out(&counter);
+ } else {
+ __add_iptables_in(&counter);
+ __add_iptables_out(&counter);
+ __add_ip6tables_in(&counter);
+ __add_ip6tables_out(&counter);
+ }
}
return FALSE;
__del_iptables_in(&counter);
__del_iptables_out(&counter);
+ __del_ip6tables_in(&counter);
+ __del_ip6tables_out(&counter);
}
return FALSE;
/* iptables rule */
__add_iptables_in(&counter);
__add_iptables_out(&counter);
+
+ /* ip6tables rule */
+ __add_ip6tables_in(&counter);
+ __add_ip6tables_out(&counter);
}
rstn_value->rst_state = STC_RESTRICTION_ACTIVATED;
__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;
}
}
static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
- stc_rstn_value_s *rstn_value,
- classid_bytes_context_s *context)
+ stc_rstn_value_s *rstn_value,
+ classid_bytes_context_s *context)
{
switch (context->counter->iotype) {
case NFACCT_COUNTER_IN:
if (rstn_value->data_counter >= rstn_value->data_warn_limit &&
rstn_value->warn_limit_crossed_notified == FALSE) {
- gboolean rv = FALSE;
+ gboolean rv;
char iftype[MAX_INT_LENGTH];
char byte[MAX_INT_LENGTH];
stc_s *stc = (stc_s *)stc_get_manager();
if (rstn_value->data_counter >= rstn_value->data_limit &&
rstn_value->rstn_limit_crossed_notified == FALSE) {
- gboolean rv = FALSE;
+ gboolean rv;
char iftype[MAX_INT_LENGTH];
char byte[MAX_INT_LENGTH];
stc_s *stc = (stc_s *)stc_get_manager();
__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->data_limit_reached = TRUE;
}
static gboolean __interface_rstn_counter_update(stc_rstn_key_s *rstn_key,
- stc_rstn_value_s *rstn_value,
- classid_bytes_context_s *context)
+ stc_rstn_value_s *rstn_value,
+ classid_bytes_context_s *context)
{
if ((rstn_value->classid == STC_TOTAL_DATACALL_CLASSID &&
- context->counter->iftype == STC_IFACE_DATACALL) ||
- (rstn_value->classid == STC_TOTAL_WIFI_CLASSID &&
- context->counter->iftype == STC_IFACE_WIFI) ||
- (rstn_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
- context->counter->iftype == STC_IFACE_BLUETOOTH)) {
+ context->counter->iftype == STC_IFACE_DATACALL) ||
+ (rstn_value->classid == STC_TOTAL_WIFI_CLASSID &&
+ context->counter->iftype == STC_IFACE_WIFI) ||
+ (rstn_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
+ context->counter->iftype == STC_IFACE_BLUETOOTH)) {
context->counter->classid = rstn_value->classid;
return __rstn_counter_update(rstn_key, rstn_value, context);
}
}
static void __app_counter_update(stc_app_key_s *app_key,
- stc_app_value_s *app_value,
- classid_bytes_context_s *context)
+ stc_app_value_s *app_value,
+ classid_bytes_context_s *context)
{
switch (context->counter->iotype) {
case NFACCT_COUNTER_IN:
}
static void __interface_counter_update(stc_app_key_s *app_key,
- stc_app_value_s *app_value,
- classid_bytes_context_s *context)
+ stc_app_value_s *app_value,
+ classid_bytes_context_s *context)
{
if ((app_value->classid == STC_TOTAL_DATACALL_CLASSID &&
- context->counter->iftype == STC_IFACE_DATACALL) ||
- (app_value->classid == STC_TOTAL_WIFI_CLASSID &&
- context->counter->iftype == STC_IFACE_WIFI) ||
- (app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
- context->counter->iftype == STC_IFACE_BLUETOOTH))
+ context->counter->iftype == STC_IFACE_DATACALL) ||
+ (app_value->classid == STC_TOTAL_WIFI_CLASSID &&
+ context->counter->iftype == STC_IFACE_WIFI) ||
+ (app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
+ context->counter->iftype == STC_IFACE_BLUETOOTH))
__app_counter_update(app_key, app_value, context);
}
+
static gboolean __apps_counter_update_foreach_classid(gpointer key,
gpointer value,
gpointer data)
__add_application_by_interface(STC_TOTAL_DATACALL);
__add_application_by_interface(STC_TOTAL_WIFI);
__add_application_by_interface(STC_TOTAL_BLUETOOTH);
+ __add_application_by_interface(STC_TOTAL_IPV4);
+ __add_application_by_interface(STC_TOTAL_IPV6);
/* creating restriction rules tree */
__update_contr_cb(NULL);