1b1b8bc3fSopenharmony_ci/* 2b1b8bc3fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License. 5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at 6b1b8bc3fSopenharmony_ci * 7b1b8bc3fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1b8bc3fSopenharmony_ci * 9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and 13b1b8bc3fSopenharmony_ci * limitations under the License. 14b1b8bc3fSopenharmony_ci */ 15b1b8bc3fSopenharmony_ci 16b1b8bc3fSopenharmony_ci#ifndef NETMANAGER_EXT_BPF_NET_FIREWALL_H 17b1b8bc3fSopenharmony_ci#define NETMANAGER_EXT_BPF_NET_FIREWALL_H 18b1b8bc3fSopenharmony_ci 19b1b8bc3fSopenharmony_ci#include <netdb.h> 20b1b8bc3fSopenharmony_ci#include <string> 21b1b8bc3fSopenharmony_ci#include <thread> 22b1b8bc3fSopenharmony_ci#include <unordered_map> 23b1b8bc3fSopenharmony_ci#include <chrono> 24b1b8bc3fSopenharmony_ci#include <functional> 25b1b8bc3fSopenharmony_ci 26b1b8bc3fSopenharmony_ci#include "bitmap_manager.h" 27b1b8bc3fSopenharmony_ci#include "bpf_mapper.h" 28b1b8bc3fSopenharmony_ci#include "i_netfirewall_callback.h" 29b1b8bc3fSopenharmony_ci#include "netfirewall/netfirewall_def.h" 30b1b8bc3fSopenharmony_ci#include "netfirewall_parcel.h" 31b1b8bc3fSopenharmony_ci#include "system_ability.h" 32b1b8bc3fSopenharmony_ci#include "system_ability_load_callback_stub.h" 33b1b8bc3fSopenharmony_ci 34b1b8bc3fSopenharmony_cinamespace OHOS::NetManagerStandard { 35b1b8bc3fSopenharmony_ci// Only used for unittest code currently 36b1b8bc3fSopenharmony_cistatic constexpr const char *FIREWALL_BPF_PATH = "/system/etc/bpf/netsys.o"; 37b1b8bc3fSopenharmony_ci 38b1b8bc3fSopenharmony_cistatic constexpr const int CONNTRACK_GC_INTTERVAL_MS = 60000; 39b1b8bc3fSopenharmony_cistatic constexpr const int RING_BUFFER_POLL_TIME_OUT_MS = -1; 40b1b8bc3fSopenharmony_ci 41b1b8bc3fSopenharmony_ci// convert ebpf types from unix style style to CPP's 42b1b8bc3fSopenharmony_ciusing Ip4Key = ip4_key; 43b1b8bc3fSopenharmony_ciusing Ip6Key = ip6_key; 44b1b8bc3fSopenharmony_ciusing Ipv4LpmKey = struct ipv4_lpm_key; 45b1b8bc3fSopenharmony_ciusing Ipv6LpmKey = struct ipv6_lpm_key; 46b1b8bc3fSopenharmony_ciusing PortKey = port_key; 47b1b8bc3fSopenharmony_ciusing ProtoKey = proto_key; 48b1b8bc3fSopenharmony_ciusing AppUidKey = appuid_key; 49b1b8bc3fSopenharmony_ciusing DefaultActionKey = default_action_key; 50b1b8bc3fSopenharmony_ciusing CurrentUserIdKey = current_user_id_key; 51b1b8bc3fSopenharmony_ciusing ActionKey = action_key; 52b1b8bc3fSopenharmony_ciusing ActionValue = action_val; 53b1b8bc3fSopenharmony_ciusing RuleCode = struct bitmap; 54b1b8bc3fSopenharmony_ciusing StreamDir = enum stream_dir; 55b1b8bc3fSopenharmony_ciusing EventType = enum event_type; 56b1b8bc3fSopenharmony_ciusing Event = struct event; 57b1b8bc3fSopenharmony_ciusing InterceptEvent = struct intercept_event; 58b1b8bc3fSopenharmony_ciusing DebugEvent = struct debug_event; 59b1b8bc3fSopenharmony_ciusing TupleEvent = struct match_tuple; 60b1b8bc3fSopenharmony_ciusing DebugType = enum debug_type; 61b1b8bc3fSopenharmony_ci 62b1b8bc3fSopenharmony_ciusing CtKey = struct ct_tuple; 63b1b8bc3fSopenharmony_ciusing CtVaule = struct ct_entry; 64b1b8bc3fSopenharmony_ci 65b1b8bc3fSopenharmony_cistruct NetAddrInfo { 66b1b8bc3fSopenharmony_ci uint32_t aiFamily; 67b1b8bc3fSopenharmony_ci union { 68b1b8bc3fSopenharmony_ci struct in_addr sin; 69b1b8bc3fSopenharmony_ci struct in6_addr sin6; 70b1b8bc3fSopenharmony_ci } aiAddr; 71b1b8bc3fSopenharmony_ci}; 72b1b8bc3fSopenharmony_ci 73b1b8bc3fSopenharmony_ci/** 74b1b8bc3fSopenharmony_ci * @brief Callback impl for LoadSystemAbility 75b1b8bc3fSopenharmony_ci */ 76b1b8bc3fSopenharmony_ciclass OnDemandLoadManagerCallback : public SystemAbilityLoadCallbackStub { 77b1b8bc3fSopenharmony_cipublic: 78b1b8bc3fSopenharmony_ci /** 79b1b8bc3fSopenharmony_ci * called when load SA success 80b1b8bc3fSopenharmony_ci * 81b1b8bc3fSopenharmony_ci * @param systemAbilityId id of SA which was loaded 82b1b8bc3fSopenharmony_ci * @param remoteObject poniter of IRemoteObject 83b1b8bc3fSopenharmony_ci */ 84b1b8bc3fSopenharmony_ci void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject) override; 85b1b8bc3fSopenharmony_ci 86b1b8bc3fSopenharmony_ci /** 87b1b8bc3fSopenharmony_ci * called when load SA fail 88b1b8bc3fSopenharmony_ci * 89b1b8bc3fSopenharmony_ci * @param systemAbilityId id of SA which was loaded 90b1b8bc3fSopenharmony_ci */ 91b1b8bc3fSopenharmony_ci void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; 92b1b8bc3fSopenharmony_ci}; 93b1b8bc3fSopenharmony_ci 94b1b8bc3fSopenharmony_ci/** 95b1b8bc3fSopenharmony_ci * Class for setup bpf maps and poll event from bpf ring buffer 96b1b8bc3fSopenharmony_ci */ 97b1b8bc3fSopenharmony_ciclass NetsysBpfNetFirewall : public NoCopyable { 98b1b8bc3fSopenharmony_cipublic: 99b1b8bc3fSopenharmony_ci static std::shared_ptr<NetsysBpfNetFirewall> GetInstance(); 100b1b8bc3fSopenharmony_ci 101b1b8bc3fSopenharmony_ci /** 102b1b8bc3fSopenharmony_ci * start to listen bpf ring buffer 103b1b8bc3fSopenharmony_ci * 104b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 105b1b8bc3fSopenharmony_ci */ 106b1b8bc3fSopenharmony_ci int32_t StartListener(); 107b1b8bc3fSopenharmony_ci 108b1b8bc3fSopenharmony_ci /* * 109b1b8bc3fSopenharmony_ci * @brief stop listen bpf ring buffer 110b1b8bc3fSopenharmony_ci * 111b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 112b1b8bc3fSopenharmony_ci */ 113b1b8bc3fSopenharmony_ci int32_t StopListener(); 114b1b8bc3fSopenharmony_ci 115b1b8bc3fSopenharmony_ci /** 116b1b8bc3fSopenharmony_ci * Set firewall rules to native 117b1b8bc3fSopenharmony_ci * 118b1b8bc3fSopenharmony_ci * @param ruleList list of NetFirewallIpRule 119b1b8bc3fSopenharmony_ci * @param isFinish transmit finish or not 120b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 121b1b8bc3fSopenharmony_ci */ 122b1b8bc3fSopenharmony_ci int32_t SetFirewallRules(const std::vector<sptr<NetFirewallBaseRule>> &ruleList, bool isFinish); 123b1b8bc3fSopenharmony_ci 124b1b8bc3fSopenharmony_ci /** 125b1b8bc3fSopenharmony_ci * Set firewall default action 126b1b8bc3fSopenharmony_ci * 127b1b8bc3fSopenharmony_ci * @param inDefault Default action of NetFirewallRuleDirection:RULE_IN 128b1b8bc3fSopenharmony_ci * @param outDefault Default action of NetFirewallRuleDirection:RULE_OUT 129b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 130b1b8bc3fSopenharmony_ci */ 131b1b8bc3fSopenharmony_ci int32_t SetFirewallDefaultAction(FirewallRuleAction inDefault, FirewallRuleAction outDefault); 132b1b8bc3fSopenharmony_ci 133b1b8bc3fSopenharmony_ci /** 134b1b8bc3fSopenharmony_ci * Set firewall current user id 135b1b8bc3fSopenharmony_ci * 136b1b8bc3fSopenharmony_ci * @param userId current user id 137b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 138b1b8bc3fSopenharmony_ci */ 139b1b8bc3fSopenharmony_ci int32_t SetFirewallCurrentUserId(int32_t userId); 140b1b8bc3fSopenharmony_ci 141b1b8bc3fSopenharmony_ci /** 142b1b8bc3fSopenharmony_ci * Clear all bpf maps 143b1b8bc3fSopenharmony_ci * 144b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 145b1b8bc3fSopenharmony_ci */ 146b1b8bc3fSopenharmony_ci int32_t ClearFirewallRules(); 147b1b8bc3fSopenharmony_ci 148b1b8bc3fSopenharmony_ci /** 149b1b8bc3fSopenharmony_ci * Register callback for recevie intercept event 150b1b8bc3fSopenharmony_ci * 151b1b8bc3fSopenharmony_ci * @param callback implement of INetFirewallCallback 152b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 153b1b8bc3fSopenharmony_ci */ 154b1b8bc3fSopenharmony_ci int32_t RegisterCallback(const sptr<NetsysNative::INetFirewallCallback> &callback); 155b1b8bc3fSopenharmony_ci 156b1b8bc3fSopenharmony_ci /** 157b1b8bc3fSopenharmony_ci * Unregister callback for recevie intercept event 158b1b8bc3fSopenharmony_ci * 159b1b8bc3fSopenharmony_ci * @param callback register callback for recevie intercept event 160b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 161b1b8bc3fSopenharmony_ci */ 162b1b8bc3fSopenharmony_ci int32_t UnregisterCallback(const sptr<NetsysNative::INetFirewallCallback> &callback); 163b1b8bc3fSopenharmony_ci 164b1b8bc3fSopenharmony_ci /** 165b1b8bc3fSopenharmony_ci * Load SA on demand 166b1b8bc3fSopenharmony_ci * 167b1b8bc3fSopenharmony_ci * @param systemAbilityId id of SA want to load 168b1b8bc3fSopenharmony_ci * @return 0 if success or -1 if an error occurred 169b1b8bc3fSopenharmony_ci */ 170b1b8bc3fSopenharmony_ci int32_t LoadSystemAbility(int32_t systemAbilityId); 171b1b8bc3fSopenharmony_ci 172b1b8bc3fSopenharmony_ci /** 173b1b8bc3fSopenharmony_ci * Set bpf prog load state 174b1b8bc3fSopenharmony_ci * 175b1b8bc3fSopenharmony_ci * @param load true if load success or false if an error occurred 176b1b8bc3fSopenharmony_ci */ 177b1b8bc3fSopenharmony_ci void SetBpfLoaded(bool load); 178b1b8bc3fSopenharmony_ci 179b1b8bc3fSopenharmony_ci /** 180b1b8bc3fSopenharmony_ci * Get bpf prog load state 181b1b8bc3fSopenharmony_ci */ 182b1b8bc3fSopenharmony_ci bool IsBpfLoaded() 183b1b8bc3fSopenharmony_ci { 184b1b8bc3fSopenharmony_ci return isBpfLoaded_; 185b1b8bc3fSopenharmony_ci } 186b1b8bc3fSopenharmony_ci 187b1b8bc3fSopenharmony_ci void AddDomainCache(const NetAddrInfo &addrInfo); 188b1b8bc3fSopenharmony_ci void ClearDomainCache(); 189b1b8bc3fSopenharmony_ci 190b1b8bc3fSopenharmony_ciprivate: 191b1b8bc3fSopenharmony_ci template <typename Key, typename Value> int ClearBpfMap(const char *path, const Key &key, Value &val) 192b1b8bc3fSopenharmony_ci { 193b1b8bc3fSopenharmony_ci (void)key; 194b1b8bc3fSopenharmony_ci (void)val; 195b1b8bc3fSopenharmony_ci BpfMapper<Key, Value> rdMap(path, BPF_F_RDONLY); 196b1b8bc3fSopenharmony_ci if (!rdMap.IsValid()) { 197b1b8bc3fSopenharmony_ci return -1; 198b1b8bc3fSopenharmony_ci } 199b1b8bc3fSopenharmony_ci std::vector<Key> keys = rdMap.GetAllKeys(); 200b1b8bc3fSopenharmony_ci if (keys.empty()) { 201b1b8bc3fSopenharmony_ci return 0; 202b1b8bc3fSopenharmony_ci } 203b1b8bc3fSopenharmony_ci BpfMapper<Key, Value> wrMap(path, BPF_F_WRONLY); 204b1b8bc3fSopenharmony_ci if (!wrMap.IsValid()) { 205b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("ClearBpfMap: wrMap is invalid"); 206b1b8bc3fSopenharmony_ci return -1; 207b1b8bc3fSopenharmony_ci } 208b1b8bc3fSopenharmony_ci if (wrMap.Clear(keys) != 0) { 209b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("ClearBpfMap: clear failed"); 210b1b8bc3fSopenharmony_ci return -1; 211b1b8bc3fSopenharmony_ci } 212b1b8bc3fSopenharmony_ci 213b1b8bc3fSopenharmony_ci return 0; 214b1b8bc3fSopenharmony_ci } 215b1b8bc3fSopenharmony_ci 216b1b8bc3fSopenharmony_ci template <typename Key, typename Value> int WriteBpfMap(const char *path, const Key &key, Value &val) 217b1b8bc3fSopenharmony_ci { 218b1b8bc3fSopenharmony_ci BpfMapper<Key, Value> map(path, BPF_F_WRONLY); 219b1b8bc3fSopenharmony_ci if (!map.IsValid()) { 220b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteBpfMap: map invalid: %{public}s", path); 221b1b8bc3fSopenharmony_ci return -1; 222b1b8bc3fSopenharmony_ci } 223b1b8bc3fSopenharmony_ci 224b1b8bc3fSopenharmony_ci if (map.Write(key, val, BPF_ANY) != 0) { 225b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteBpfMap: map write failed"); 226b1b8bc3fSopenharmony_ci return -1; 227b1b8bc3fSopenharmony_ci } 228b1b8bc3fSopenharmony_ci 229b1b8bc3fSopenharmony_ci return 0; 230b1b8bc3fSopenharmony_ci } 231b1b8bc3fSopenharmony_ci 232b1b8bc3fSopenharmony_ci NetsysBpfNetFirewall(); 233b1b8bc3fSopenharmony_ci 234b1b8bc3fSopenharmony_ci static void StartConntrackGcThread(void); 235b1b8bc3fSopenharmony_ci 236b1b8bc3fSopenharmony_ci static void RingBufferListenThread(void); 237b1b8bc3fSopenharmony_ci 238b1b8bc3fSopenharmony_ci void StopConntrackGc(); 239b1b8bc3fSopenharmony_ci 240b1b8bc3fSopenharmony_ci static int HandleEvent(void *ctx, void *data, size_t len); 241b1b8bc3fSopenharmony_ci 242b1b8bc3fSopenharmony_ci static void HandleTupleEvent(TupleEvent *ev); 243b1b8bc3fSopenharmony_ci 244b1b8bc3fSopenharmony_ci static void HandleInterceptEvent(InterceptEvent *ev); 245b1b8bc3fSopenharmony_ci 246b1b8bc3fSopenharmony_ci static void HandleDebugEvent(DebugEvent *ev); 247b1b8bc3fSopenharmony_ci 248b1b8bc3fSopenharmony_ci bool ShouldSkipNotify(sptr<InterceptRecord> record); 249b1b8bc3fSopenharmony_ci 250b1b8bc3fSopenharmony_ci void NotifyInterceptEvent(InterceptEvent *info); 251b1b8bc3fSopenharmony_ci 252b1b8bc3fSopenharmony_ci static void ConntrackGcTask(); 253b1b8bc3fSopenharmony_ci 254b1b8bc3fSopenharmony_ci void ClearBpfFirewallRules(NetFirewallRuleDirection direction); 255b1b8bc3fSopenharmony_ci 256b1b8bc3fSopenharmony_ci void WriteSrcIpv4BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 257b1b8bc3fSopenharmony_ci 258b1b8bc3fSopenharmony_ci void WriteSrcIpv6BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 259b1b8bc3fSopenharmony_ci 260b1b8bc3fSopenharmony_ci void WriteDstIpv4BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 261b1b8bc3fSopenharmony_ci 262b1b8bc3fSopenharmony_ci void WriteDstIpv6BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 263b1b8bc3fSopenharmony_ci 264b1b8bc3fSopenharmony_ci void WriteSrcPortBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 265b1b8bc3fSopenharmony_ci 266b1b8bc3fSopenharmony_ci void WriteDstPortBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 267b1b8bc3fSopenharmony_ci 268b1b8bc3fSopenharmony_ci void WriteProtoBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 269b1b8bc3fSopenharmony_ci 270b1b8bc3fSopenharmony_ci void WriteAppUidBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 271b1b8bc3fSopenharmony_ci 272b1b8bc3fSopenharmony_ci void WriteUidBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 273b1b8bc3fSopenharmony_ci 274b1b8bc3fSopenharmony_ci void WriteActionBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction); 275b1b8bc3fSopenharmony_ci 276b1b8bc3fSopenharmony_ci int32_t SetBpfFirewallRules(const std::vector<sptr<NetFirewallIpRule>> &ruleList, 277b1b8bc3fSopenharmony_ci NetFirewallRuleDirection direction); 278b1b8bc3fSopenharmony_ci 279b1b8bc3fSopenharmony_ci int32_t SetFirewallIpRules(const std::vector<sptr<NetFirewallIpRule>> &ruleList); 280b1b8bc3fSopenharmony_ci 281b1b8bc3fSopenharmony_ci static std::shared_ptr<NetsysBpfNetFirewall> instance_; 282b1b8bc3fSopenharmony_ci static bool isBpfLoaded_; 283b1b8bc3fSopenharmony_ci static bool keepListen_; 284b1b8bc3fSopenharmony_ci std::unique_ptr<std::thread> thread_; 285b1b8bc3fSopenharmony_ci std::vector<sptr<NetsysNative::INetFirewallCallback>> callbacks_; 286b1b8bc3fSopenharmony_ci sptr<InterceptRecord> oldRecord_ = nullptr; 287b1b8bc3fSopenharmony_ci static bool keepGc_; 288b1b8bc3fSopenharmony_ci std::unique_ptr<std::thread> gcThread_; 289b1b8bc3fSopenharmony_ci static std::unique_ptr<BpfMapper<CtKey, CtVaule>> ctRdMap_, ctWrMap_; 290b1b8bc3fSopenharmony_ci std::vector<sptr<NetFirewallIpRule>> firewallIpRules_; 291b1b8bc3fSopenharmony_ci}; 292b1b8bc3fSopenharmony_ci} // namespace OHOS::NetManagerStandard 293b1b8bc3fSopenharmony_ci#endif /* NETMANAGER_EXT_BPF_NET_FIREWALL_H */ 294