tizen 2.3 release
[kernel/api/system-resource.git] / src / network / nf-restriction.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /*
21  * @file nfacct-restriction.c
22  *
23  * @desc Implementation for set up/down restrictions.
24  *
25  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
26  *
27  */
28
29 #include "const.h"
30 #include "datausage-common.h"
31 #include "stdlib.h"
32 #include "macro.h"
33 #include "module-data.h"
34 #include "netlink-restriction.h"
35 #include "nfacct-rule.h"
36 #include "resourced.h"
37 #include "trace.h"
38
39 static resourced_ret_c apply_net_restriction(struct nfacct_rule *rule,
40                         const int send_limit, const int rcv_limit)
41 {
42         nfacct_rule_jump jump = rule->intend == NFACCT_WARN ? NFACCT_JUMP_ACCEPT :
43                         NFACCT_JUMP_REJECT;
44
45         return produce_net_rule(rule, send_limit, rcv_limit,
46                 NFACCT_ACTION_APPEND, jump,
47                 NFACCT_COUNTER_IN | NFACCT_COUNTER_OUT);
48 }
49
50 static resourced_ret_c revert_net_restriction(struct nfacct_rule *rule,
51                          const int send_limit, const int rcv_limit)
52 {
53         nfacct_rule_jump jump = rule->intend == NFACCT_WARN ? NFACCT_JUMP_ACCEPT :
54                         NFACCT_JUMP_REJECT;
55
56         return produce_net_rule(rule, send_limit, rcv_limit,
57                 NFACCT_ACTION_DELETE, jump,
58                 NFACCT_COUNTER_IN | NFACCT_COUNTER_OUT);
59
60 }
61
62 static resourced_ret_c exclude_net_restriction(struct nfacct_rule *rule)
63 {
64         /* Idea to remove old counter and insert new one at first position
65          * iptables has following architecture: it gets all entries from kernel
66          * modifies this list and returns it back, without iptables it could be
67          * done for one step, but with iptables cmd 2 steps is necessary */
68         rule->intend = NFACCT_COUNTER;
69         resourced_ret_c ret = produce_net_rule(rule, 0, 0,
70                 NFACCT_ACTION_DELETE, NFACCT_JUMP_UNKNOWN,
71                 NFACCT_COUNTER_IN | NFACCT_COUNTER_OUT);
72
73         ret_value_msg_if(ret != RESOURCED_ERROR_NONE, ret, "Failed to delete");
74
75         return produce_net_rule(rule, 0, 0,
76                 NFACCT_ACTION_INSERT, NFACCT_JUMP_ACCEPT,
77                 NFACCT_COUNTER_IN | NFACCT_COUNTER_OUT);
78 }
79
80 resourced_ret_c send_net_restriction(const enum traffic_restriction_type rst_type,
81                          const u_int32_t classid,
82                          const resourced_iface_type iftype,
83                          const int send_limit, const int rcv_limit,
84                          const int snd_warning_threshold,
85                          const int rcv_warning_threshold)
86 {
87         int ret;
88         struct shared_modules_data *m_data = get_shared_modules_data();
89         struct counter_arg *carg;
90         struct nfacct_rule rule = {
91                 .name = {0},
92                 .ifname = {0},
93                 0,
94         };
95
96         ret_value_msg_if(m_data == NULL, RESOURCED_ERROR_FAIL, "Empty shared modules data");
97
98         carg = m_data->carg;
99         ret_value_msg_if(carg == NULL, RESOURCED_ERROR_FAIL, "Empty counter");
100
101
102         rule.classid = classid;
103         rule.iftype = iftype;
104         rule.carg = carg;
105
106         if (rst_type == RST_SET) {
107                 if (snd_warning_threshold ||
108                         rcv_warning_threshold) {
109                         rule.intend = NFACCT_WARN;
110                         ret = apply_net_restriction(&rule,
111                                 snd_warning_threshold, rcv_warning_threshold);
112                         ret_value_msg_if(ret != RESOURCED_ERROR_NONE, ret,
113                                 "Can't apply network restriction");
114                 }
115                 rule.intend = NFACCT_BLOCK;
116                 ret = apply_net_restriction(&rule, send_limit, rcv_limit);
117                 ret_value_msg_if(ret != RESOURCED_ERROR_NONE, ret,
118                                 "Can't apply network restriction");
119         } else if (rst_type == RST_UNSET) {
120                 rule.intend = NFACCT_WARN;
121                 ret = revert_net_restriction(&rule,
122                         snd_warning_threshold, rcv_warning_threshold);
123                 ret_value_msg_if(ret != RESOURCED_ERROR_NONE, ret,
124                         "Can't revert network restriction");
125                 rule.intend = NFACCT_BLOCK;
126                 return revert_net_restriction(&rule, send_limit,
127                         rcv_limit);
128         } else if (rst_type == RST_EXCLUDE)
129                 return exclude_net_restriction(&rule);
130
131         return RESOURCED_ERROR_NONE;
132 }