summaryrefslogtreecommitdiff
path: root/server/ClatdController.h
blob: 4b7c60bbd475b6e3f749bd5063ce7cb7253ab107 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _CLATD_CONTROLLER_H
#define _CLATD_CONTROLLER_H

#include <map>
#include <mutex>
#include <string>

#include <linux/if.h>
#include <netinet/in.h>

#include <android-base/thread_annotations.h>

#include "Fwmark.h"
#include "NetdConstants.h"
#include "bpf/BpfMap.h"
#include "netdbpf/bpf_shared.h"
#include "netdutils/DumpWriter.h"

namespace android {
namespace net {

class NetworkController;

class ClatdController {
  public:
    explicit ClatdController(NetworkController* controller) EXCLUDES(mutex)
        : mNetCtrl(controller){};
    virtual ~ClatdController() EXCLUDES(mutex){};

    /* First thing init/startClatd/stopClatd/dump do is grab the mutex. */
    void init(void) EXCLUDES(mutex);

    int startClatd(const std::string& interface, const std::string& nat64Prefix,
                   std::string* v6Addr) EXCLUDES(mutex);
    int stopClatd(const std::string& interface) EXCLUDES(mutex);

    void dump(netdutils::DumpWriter& dw) EXCLUDES(mutex);

    static constexpr const char LOCAL_RAW_PREROUTING[] = "clat_raw_PREROUTING";

  private:
    struct ClatdTracker {
        pid_t pid = -1;
        unsigned ifIndex;
        char iface[IFNAMSIZ];
        unsigned v4ifIndex;
        char v4iface[IFNAMSIZ];
        Fwmark fwmark;
        char fwmarkString[UINT32_STRLEN];
        in_addr v4;
        char v4Str[INET_ADDRSTRLEN];
        in6_addr v6;
        char v6Str[INET6_ADDRSTRLEN];
        in6_addr pfx96;
        char pfx96String[INET6_ADDRSTRLEN];

        int init(unsigned networkId, const std::string& interface, const std::string& v4interface,
                 const std::string& nat64Prefix);
    };

    std::mutex mutex;

    const NetworkController* mNetCtrl GUARDED_BY(mutex);
    std::map<std::string, ClatdTracker> mClatdTrackers GUARDED_BY(mutex);
    ClatdTracker* getClatdTracker(const std::string& interface) REQUIRES(mutex);

    void dumpEgress(netdutils::DumpWriter& dw) REQUIRES(mutex);
    void dumpIngress(netdutils::DumpWriter& dw) REQUIRES(mutex);
    void dumpTrackers(netdutils::DumpWriter& dw) REQUIRES(mutex);

    static in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen);
    static int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
                                   in6_addr* v6);
    static void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);

    bpf::BpfMap<ClatEgress4Key, ClatEgress4Value> mClatEgress4Map GUARDED_BY(mutex);
    bpf::BpfMap<ClatIngress6Key, ClatIngress6Value> mClatIngress6Map GUARDED_BY(mutex);

    void maybeStartBpf(const ClatdTracker& tracker) REQUIRES(mutex);
    void maybeStopBpf(const ClatdTracker& tracker) REQUIRES(mutex);
    void setIptablesDropRule(bool add, const char* iface, const char* pfx96Str, const char* v6Str)
            REQUIRES(mutex);

    // For testing.
    friend class ClatdControllerTest;

    static bool (*isIpv4AddressFreeFunc)(in_addr_t);
    static bool isIpv4AddressFree(in_addr_t addr);
    static int (*iptablesRestoreFunction)(IptablesTarget target, const std::string& commands);
};

}  // namespace net
}  // namespace android

#endif