1 /* 2 * Copyright (C) 2008 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 17 #ifndef _CLATD_CONTROLLER_H 18 #define _CLATD_CONTROLLER_H 19 20 #include <map> 21 #include <mutex> 22 #include <string> 23 24 #include <linux/if.h> 25 #include <netinet/in.h> 26 27 #include <android-base/thread_annotations.h> 28 29 #include "Fwmark.h" 30 #include "NetdConstants.h" 31 #include "bpf/BpfMap.h" 32 #include "netdbpf/bpf_shared.h" 33 #include "netdutils/DumpWriter.h" 34 35 namespace android { 36 namespace net { 37 38 class NetworkController; 39 40 class ClatdController { 41 public: ClatdController(NetworkController * controller)42 explicit ClatdController(NetworkController* controller) EXCLUDES(mutex) 43 : mNetCtrl(controller){}; ~ClatdController()44 virtual ~ClatdController() EXCLUDES(mutex){}; 45 46 /* First thing init/startClatd/stopClatd/dump do is grab the mutex. */ 47 void init(void) EXCLUDES(mutex); 48 49 int startClatd(const std::string& interface, const std::string& nat64Prefix, 50 std::string* v6Addr) EXCLUDES(mutex); 51 int stopClatd(const std::string& interface) EXCLUDES(mutex); 52 53 void dump(netdutils::DumpWriter& dw) EXCLUDES(mutex); 54 55 static constexpr const char LOCAL_RAW_PREROUTING[] = "clat_raw_PREROUTING"; 56 57 private: 58 struct ClatdTracker { 59 pid_t pid = -1; 60 unsigned ifIndex; 61 char iface[IFNAMSIZ]; 62 unsigned v4ifIndex; 63 char v4iface[IFNAMSIZ]; 64 Fwmark fwmark; 65 char fwmarkString[UINT32_STRLEN]; 66 unsigned netId; 67 char netIdString[UINT32_STRLEN]; 68 in_addr v4; 69 char v4Str[INET_ADDRSTRLEN]; 70 in6_addr v6; 71 char v6Str[INET6_ADDRSTRLEN]; 72 in6_addr pfx96; 73 char pfx96String[INET6_ADDRSTRLEN]; 74 75 int init(unsigned networkId, const std::string& interface, const std::string& v4interface, 76 const std::string& nat64Prefix); 77 }; 78 79 std::mutex mutex; 80 81 const NetworkController* mNetCtrl GUARDED_BY(mutex); 82 std::map<std::string, ClatdTracker> mClatdTrackers GUARDED_BY(mutex); 83 ClatdTracker* getClatdTracker(const std::string& interface) REQUIRES(mutex); 84 85 static in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen); 86 static int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix, 87 in6_addr* v6); 88 static void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix); 89 90 enum eClatEbpfMode { 91 ClatEbpfDisabled, // <4.9 kernel || <P api shipping level -- will not work 92 ClatEbpfMaybe, // >=4.9 kernel && P api shipping level -- might work 93 ClatEbpfEnabled, // >=4.9 kernel && >=Q api shipping level -- must work 94 }; 95 eClatEbpfMode mClatEbpfMode GUARDED_BY(mutex); getEbpfMode()96 eClatEbpfMode getEbpfMode() EXCLUDES(mutex) { 97 std::lock_guard guard(mutex); 98 return mClatEbpfMode; 99 } 100 101 base::unique_fd mNetlinkFd GUARDED_BY(mutex); 102 bpf::BpfMap<ClatIngressKey, ClatIngressValue> mClatIngressMap GUARDED_BY(mutex); 103 104 void maybeStartBpf(const ClatdTracker& tracker) REQUIRES(mutex); 105 void maybeStopBpf(const ClatdTracker& tracker) REQUIRES(mutex); 106 void maybeSetIptablesDropRule(bool add, const char* pfx96Str, const char* v6Str) 107 REQUIRES(mutex); 108 109 // For testing. 110 friend class ClatdControllerTest; 111 112 static bool (*isIpv4AddressFreeFunc)(in_addr_t); 113 static bool isIpv4AddressFree(in_addr_t addr); 114 static int (*iptablesRestoreFunction)(IptablesTarget target, const std::string& commands); 115 }; 116 117 } // namespace net 118 } // namespace android 119 120 #endif 121