• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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