1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef _BANDWIDTH_CONTROLLER_H
17 #define _BANDWIDTH_CONTROLLER_H
18 
19 #include <map>
20 #include <set>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 #include <mutex>
25 
26 #include "NetdConstants.h"
27 
28 class BandwidthController {
29 public:
30     std::mutex lock;
31 
32     BandwidthController();
33 
34     int setupIptablesHooks();
35     void setBpfEnabled(bool isEnabled);
36 
37     int enableBandwidthControl();
38     int disableBandwidthControl();
39     int enableDataSaver(bool enable);
40 
41     int setInterfaceSharedQuota(const std::string& iface, int64_t bytes);
42     int getInterfaceSharedQuota(int64_t *bytes);
43     int removeInterfaceSharedQuota(const std::string& iface);
44 
45     int setInterfaceQuota(const std::string& iface, int64_t bytes);
46     int getInterfaceQuota(const std::string& iface, int64_t* bytes);
47     int removeInterfaceQuota(const std::string& iface);
48 
49     // TODO: Remove after removing these commands in CommandListener
50     int addNaughtyApps(int numUids, const char* const appUids[]);
51     int removeNaughtyApps(int numUids, const char* const appUids[]);
52     int addNiceApps(int numUids, const char* const appUids[]);
53     int removeNiceApps(int numUids, const char* const appUids[]);
54 
55     int addNaughtyApps(const std::vector<std::string>& appStrUid);
56     int removeNaughtyApps(const std::vector<std::string>& appStrUid);
57     int addNiceApps(const std::vector<std::string>& appStrUid);
58     int removeNiceApps(const std::vector<std::string>& appStrUid);
59 
60     int setGlobalAlert(int64_t bytes);
61     int removeGlobalAlert();
62     int setGlobalAlertInForwardChain();
63     int removeGlobalAlertInForwardChain();
64 
65     int setSharedAlert(int64_t bytes);
66     int removeSharedAlert();
67 
68     int setInterfaceAlert(const std::string& iface, int64_t bytes);
69     int removeInterfaceAlert(const std::string& iface);
70 
71     static const char LOCAL_INPUT[];
72     static const char LOCAL_FORWARD[];
73     static const char LOCAL_OUTPUT[];
74     static const char LOCAL_RAW_PREROUTING[];
75     static const char LOCAL_MANGLE_POSTROUTING[];
76     static const char LOCAL_GLOBAL_ALERT[];
77 
78     enum IptJumpOp { IptJumpReject, IptJumpReturn, IptJumpNoAdd };
79     enum IptOp { IptOpInsert, IptOpDelete };
80 
81   private:
82     struct QuotaInfo {
83         int64_t quota;
84         int64_t alert;
85     };
86 
87     enum IptIpVer { IptIpV4, IptIpV6 };
88     enum IptFullOp { IptFullOpInsert, IptFullOpDelete, IptFullOpAppend };
89     enum QuotaType { QuotaUnique, QuotaShared };
90     enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
91 #if LOG_NDEBUG
92     enum IptFailureLog { IptFailShow, IptFailHide };
93 #else
94     enum IptFailureLog { IptFailShow, IptFailHide = IptFailShow };
95 #endif
96 
97     std::string makeDataSaverCommand(IptablesTarget target, bool enable);
98 
99     int manipulateSpecialApps(const std::vector<std::string>& appStrUids, const std::string& chain,
100                               IptJumpOp jumpHandling, IptOp appOp);
101 
102     int runIptablesAlertCmd(IptOp op, const std::string& alertName, int64_t bytes);
103     int runIptablesAlertFwdCmd(IptOp op, const std::string& alertName, int64_t bytes);
104 
105     int updateQuota(const std::string& alertName, int64_t bytes);
106 
107     int setCostlyAlert(const std::string& costName, int64_t bytes, int64_t* alertBytes);
108     int removeCostlyAlert(const std::string& costName, int64_t* alertBytes);
109 
110     /*
111      * Attempt to find the bw_costly_* tables that need flushing,
112      * and flush them.
113      * If doClean then remove the tables also.
114      * Deals with both ip4 and ip6 tables.
115      */
116     void flushExistingCostlyTables(bool doClean);
117     static void parseAndFlushCostlyTables(const std::string& ruleList, bool doRemove);
118 
119     /*
120      * Attempt to flush our tables.
121      * If doClean then remove them also.
122      * Deals with both ip4 and ip6 tables.
123      */
124     void flushCleanTables(bool doClean);
125 
126     // For testing.
127     friend class BandwidthControllerTest;
128     static int (*execFunction)(int, char **, int *, bool, bool);
129     static FILE *(*popenFunction)(const char *, const char *);
130     static int (*iptablesRestoreFunction)(IptablesTarget, const std::string&, std::string *);
131 
132     static const char *opToString(IptOp op);
133     static const char *jumpToString(IptJumpOp jumpHandling);
134 
135     bool mBpfSupported = false;
136 
137     int64_t mSharedQuotaBytes = 0;
138     int64_t mSharedAlertBytes = 0;
139     int64_t mGlobalAlertBytes = 0;
140 
141     std::map<std::string, QuotaInfo> mQuotaIfaces;
142     std::set<std::string> mSharedQuotaIfaces;
143 };
144 
145 #endif
146