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 in_addr v4; 67 char v4Str[INET_ADDRSTRLEN]; 68 in6_addr v6; 69 char v6Str[INET6_ADDRSTRLEN]; 70 in6_addr pfx96; 71 char pfx96String[INET6_ADDRSTRLEN]; 72 73 int init(unsigned networkId, const std::string& interface, const std::string& v4interface, 74 const std::string& nat64Prefix); 75 }; 76 77 std::mutex mutex; 78 79 const NetworkController* mNetCtrl GUARDED_BY(mutex); 80 std::map<std::string, ClatdTracker> mClatdTrackers GUARDED_BY(mutex); 81 ClatdTracker* getClatdTracker(const std::string& interface) REQUIRES(mutex); 82 83 void dumpEgress(netdutils::DumpWriter& dw) REQUIRES(mutex); 84 void dumpIngress(netdutils::DumpWriter& dw) REQUIRES(mutex); 85 void dumpTrackers(netdutils::DumpWriter& dw) REQUIRES(mutex); 86 87 static in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen); 88 static int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix, 89 in6_addr* v6); 90 static void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix); 91 92 enum eClatEbpfMode { 93 ClatEbpfDisabled, // <4.9 kernel || <P api shipping level -- will not work 94 ClatEbpfMaybe, // >=4.9 kernel && P api shipping level -- might work 95 ClatEbpfEnabled, // >=4.9 kernel && >=Q api shipping level -- must work 96 }; 97 eClatEbpfMode mClatEbpfMode GUARDED_BY(mutex); getEbpfMode()98 eClatEbpfMode getEbpfMode() EXCLUDES(mutex) { 99 std::lock_guard guard(mutex); 100 return mClatEbpfMode; 101 } 102 103 bpf::BpfMap<ClatEgressKey, ClatEgressValue> mClatEgressMap GUARDED_BY(mutex); 104 bpf::BpfMap<ClatIngressKey, ClatIngressValue> mClatIngressMap GUARDED_BY(mutex); 105 106 void maybeStartBpf(const ClatdTracker& tracker) REQUIRES(mutex); 107 void maybeStopBpf(const ClatdTracker& tracker) REQUIRES(mutex); 108 void setIptablesDropRule(bool add, const char* iface, const char* pfx96Str, const char* v6Str) 109 REQUIRES(mutex); 110 111 // For testing. 112 friend class ClatdControllerTest; 113 114 static bool (*isIpv4AddressFreeFunc)(in_addr_t); 115 static bool isIpv4AddressFree(in_addr_t addr); 116 static int (*iptablesRestoreFunction)(IptablesTarget target, const std::string& commands); 117 }; 118 119 } // namespace net 120 } // namespace android 121 122 #endif 123