diff --git a/aosp/packages/modules/adb/daemon/transport_local.cpp b/aosp/packages/modules/adb/daemon/transport_local.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a06be3381c709a811f1988332fe8a0d9cd41c4ce --- /dev/null +++ b/aosp/packages/modules/adb/daemon/transport_local.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007 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. + */ + +#define TRACE_TAG TRANSPORT + +#include "sysdeps.h" +#include "transport.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if !ADB_HOST +#include +#endif + +#include "adb.h" +#include "adb_io.h" +#include "adb_unique_fd.h" +#include "adb_utils.h" +#include "socket_spec.h" +#include "sysdeps/chrono.h" + +void server_socket_thread(std::function listen_func, + std::string_view addr, int family) { + adb_thread_setname("server socket"); + + unique_fd serverfd; + std::string error; + + while (serverfd == -1) { + errno = 0; + serverfd = listen_func(addr, &error, family); + if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) { + D("unrecoverable error: '%s'", error.c_str()); + return; + } else if (serverfd < 0) { + D("server: cannot bind socket yet: %s", error.c_str()); + std::this_thread::sleep_for(1s); + continue; + } + close_on_exec(serverfd.get()); + } + + while (true) { + D("server: trying to get new connection from fd %d", serverfd.get()); + unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr)); + if (fd >= 0) { + D("server: new connection on fd %d", fd.get()); + close_on_exec(fd.get()); + disable_tcp_nagle(fd.get()); + std::string serial = android::base::StringPrintf("host-%d", fd.get()); + // We don't care about port value in "register_socket_transport" as it is used + // only from ADB_HOST. "server_socket_thread" is never called from ADB_HOST. + register_socket_transport( + std::move(fd), std::move(serial), 0, 1, + [](atransport*) { return ReconnectResult::Abort; }, false); + } + } + D("transport: server_socket_thread() exiting family=%d", family); +} + +unique_fd adb_listen(std::string_view addr, std::string* error, int family) { + return unique_fd{socket_spec_listen(addr, error, nullptr, family)}; +} + +void local_init(const std::string& addr) { + D("transport: local server init"); + std::thread(server_socket_thread, adb_listen, addr, AF_INET).detach(); + std::thread(server_socket_thread, adb_listen, addr, AF_INET6).detach(); +} + +int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) { + t->type = kTransportLocal; + auto fd_connection = std::make_unique(std::move(fd)); + t->SetConnection(std::make_unique(std::move(fd_connection))); + return 0; +} + diff --git a/aosp/packages/modules/adb/socket_spec.cpp b/aosp/packages/modules/adb/socket_spec.cpp index 29478a87929916ab9c8727d4828e288612bce75c..743878eee31e40916740c8495e9b4f24cd5a60ec 100644 --- a/aosp/packages/modules/adb/socket_spec.cpp +++ b/aosp/packages/modules/adb/socket_spec.cpp @@ -360,7 +360,7 @@ int helpers_network_server(uint16_t family, int port, std::string *error) for (ifa = ifa_list; ifa != nullptr; ifa = ifa->ifa_next) { if (ifa->ifa_addr == nullptr || ifa->ifa_name == nullptr || - std::string(ifa->ifa_name) != "eth0") { + std::string(ifa->ifa_name) != "wlan0") { continue; } if (ifa->ifa_addr->sa_family == AF_INET) { @@ -409,7 +409,7 @@ int helpers_network_server(uint16_t family, int port, std::string *error) return sock; } -int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port) { +int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port, int family) { if (spec.starts_with("tcp:")) { std::string hostname; int port; @@ -417,7 +417,7 @@ int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_ return -1; } - int result = helpers_network_server(AF_INET, port, error); + int result = helpers_network_server(family, port, error); if (result >= 0 && resolved_port) { *resolved_port = adb_socket_get_local_port(result); } @@ -531,3 +531,4 @@ int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_ *error += spec; return -1; } + diff --git a/aosp/packages/modules/adb/socket_spec.h b/aosp/packages/modules/adb/socket_spec.h index 95cd00d16d7e9721962b987c11e01f70695283c1..2a3cf0241b0b9ab690cbccc8f59e27e9a668bccb 100644 --- a/aosp/packages/modules/adb/socket_spec.h +++ b/aosp/packages/modules/adb/socket_spec.h @@ -18,6 +18,7 @@ #include #include +#include #include "adb_unique_fd.h" @@ -32,9 +33,10 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std int helpers_network_server(uint16_t family, int port, std::string *error); -int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr); +int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port = nullptr, int family = AF_INET); bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port, std::string* serial, std::string* error); int get_host_socket_spec_port(std::string_view spec, std::string* error); + diff --git a/aosp/packages/modules/adb/transport.cpp b/aosp/packages/modules/adb/transport.cpp index bb0ef94d7b4b1e01cdfa3f2cfe75705994893b63..f3e51bf6ac803c448718c059ad4644d5d7ba5b0d 100644 --- a/aosp/packages/modules/adb/transport.cpp +++ b/aosp/packages/modules/adb/transport.cpp @@ -1717,3 +1717,4 @@ void atransport::ResetKeys() { keys_.clear(); } #endif + diff --git a/aosp/packages/modules/adb/transport.h b/aosp/packages/modules/adb/transport.h new file mode 100644 index 0000000000000000000000000000000000000000..c56c6b1f75039acc5343209edcee680ed1d3a8ab --- /dev/null +++ b/aosp/packages/modules/adb/transport.h @@ -0,0 +1,548 @@ +/* + * Copyright (C) 2011 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 __TRANSPORT_H +#define __TRANSPORT_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "adb.h" +#include "adb_unique_fd.h" +#include "types.h" + +// Even though the feature set is used as a set, we only have a dozen or two +// of available features at any moment. Vector works much better in terms of +// both memory usage and performance for these sizes. +using FeatureSet = std::vector; + +namespace adb { +namespace tls { + +class TlsConnection; + +} // namespace tls +} // namespace adb + +const FeatureSet& supported_features(); + +// Encodes and decodes FeatureSet objects into human-readable strings. +std::string FeatureSetToString(const FeatureSet& features); +FeatureSet StringToFeatureSet(const std::string& features_string); + +// Returns true if both local features and |feature_set| support |feature|. +bool CanUseFeature(const FeatureSet& feature_set, const std::string& feature); + +// Do not use any of [:;=,] in feature strings, they have special meaning +// in the connection banner. +extern const char* const kFeatureShell2; +// The 'cmd' command is available +extern const char* const kFeatureCmd; +extern const char* const kFeatureStat2; +extern const char* const kFeatureLs2; +// The server is running with libusb enabled. +extern const char* const kFeatureLibusb; +// adbd supports `push --sync`. +extern const char* const kFeaturePushSync; +// adbd supports installing .apex packages. +extern const char* const kFeatureApex; +// adbd has b/110953234 fixed. +extern const char* const kFeatureFixedPushMkdir; +// adbd supports android binder bridge (abb) in interactive mode using shell protocol. +extern const char* const kFeatureAbb; +// adbd supports abb using raw pipe. +extern const char* const kFeatureAbbExec; +// adbd properly updates symlink timestamps on push. +extern const char* const kFeatureFixedPushSymlinkTimestamp; +// Implement `adb remount` via shelling out to /system/bin/remount. +extern const char* const kFeatureRemountShell; +// adbd supports `track-app` service reporting debuggable/profileable apps. +extern const char* const kFeatureTrackApp; +// adbd supports version 2 of send/recv. +extern const char* const kFeatureSendRecv2; +// adbd supports brotli for send/recv v2. +extern const char* const kFeatureSendRecv2Brotli; +// adbd supports LZ4 for send/recv v2. +extern const char* const kFeatureSendRecv2LZ4; +// adbd supports Zstd for send/recv v2. +extern const char* const kFeatureSendRecv2Zstd; +// adbd supports dry-run send for send/recv v2. +extern const char* const kFeatureSendRecv2DryRunSend; +// adbd supports delayed acks. +extern const char* const kFeatureDelayedAck; + +TransportId NextTransportId(); + +// Abstraction for a non-blocking packet transport. +struct Connection { + Connection() = default; + virtual ~Connection() = default; + + void SetTransport(atransport* transport) { transport_ = transport; } + + virtual bool Write(std::unique_ptr packet) = 0; + + virtual void Start() = 0; + virtual void Stop() = 0; + + virtual bool DoTlsHandshake(RSA* key, std::string* auth_key = nullptr) = 0; + + // Stop, and reset the device if it's a USB connection. + virtual void Reset(); + + virtual bool Attach(std::string* error) { + *error = "transport type doesn't support attach"; + return false; + } + + virtual bool Detach(std::string* error) { + *error = "transport type doesn't support detach"; + return false; + } + + std::string Serial() const; + + atransport* transport_ = nullptr; + + static std::unique_ptr FromFd(unique_fd fd); + + enum ConnectionSpeed { + UNKNOWN = 0, + USB1_0 = 1, + USB2_0_FULL = 12, + USB2_0_HIGH = 480, + USB3_0 = 5000, + USB3_1 = 10000, + USB3_2 = 20000, + USB4_0 = 40000, + }; + + virtual ConnectionSpeed NegotiatedSpeedMbps() { return UNKNOWN; } + virtual ConnectionSpeed MaxSpeedMbps() { return UNKNOWN; } +}; + +// Abstraction for a blocking packet transport. +struct BlockingConnection { + BlockingConnection() = default; + BlockingConnection(const BlockingConnection& copy) = delete; + BlockingConnection(BlockingConnection&& move) = delete; + + // Destroy a BlockingConnection. Formerly known as 'Close' in atransport. + virtual ~BlockingConnection() = default; + + // Read/Write a packet. These functions are concurrently called from a transport's reader/writer + // threads. + virtual bool Read(apacket* packet) = 0; + virtual bool Write(apacket* packet) = 0; + + virtual bool DoTlsHandshake(RSA* key, std::string* auth_key = nullptr) = 0; + + // Terminate a connection. + // This method must be thread-safe, and must cause concurrent Reads/Writes to terminate. + // Formerly known as 'Kick' in atransport. + virtual void Close() = 0; + + // Terminate a connection, and reset it. + virtual void Reset() = 0; +}; + +struct BlockingConnectionAdapter : public Connection { + explicit BlockingConnectionAdapter(std::unique_ptr connection); + + virtual ~BlockingConnectionAdapter(); + + virtual bool Write(std::unique_ptr packet) override final; + + virtual void Start() override final; + virtual void Stop() override final; + virtual bool DoTlsHandshake(RSA* key, std::string* auth_key) override final; + + virtual void Reset() override final; + + private: + void StartReadThread() REQUIRES(mutex_); + bool started_ GUARDED_BY(mutex_) = false; + bool stopped_ GUARDED_BY(mutex_) = false; + + std::unique_ptr underlying_; + std::thread read_thread_ GUARDED_BY(mutex_); + std::thread write_thread_ GUARDED_BY(mutex_); + + std::deque> write_queue_ GUARDED_BY(mutex_); + std::mutex mutex_; + std::condition_variable cv_; + + std::once_flag error_flag_; +}; + +struct FdConnection : public BlockingConnection { + explicit FdConnection(unique_fd fd); + ~FdConnection(); + + bool Read(apacket* packet) override final; + bool Write(apacket* packet) override final; + bool DoTlsHandshake(RSA* key, std::string* auth_key) override final; + + void Close() override; + virtual void Reset() override final { Close(); } + + private: + bool DispatchRead(void* buf, size_t len); + bool DispatchWrite(void* buf, size_t len); + + unique_fd fd_; + std::unique_ptr tls_; +}; + +// Waits for a transport's connection to be not pending. This is a separate +// object so that the transport can be destroyed and another thread can be +// notified of it in a race-free way. +class ConnectionWaitable { + public: + ConnectionWaitable() = default; + ~ConnectionWaitable() = default; + + // Waits until the first CNXN packet has been received by the owning + // atransport, or the specified timeout has elapsed. Can be called from any + // thread. + // + // Returns true if the CNXN packet was received in a timely fashion, false + // otherwise. + bool WaitForConnection(std::chrono::milliseconds timeout); + + // Can be called from any thread when the connection stops being pending. + // Only the first invocation will be acknowledged, the rest will be no-ops. + void SetConnectionEstablished(bool success); + + private: + bool connection_established_ GUARDED_BY(mutex_) = false; + bool connection_established_ready_ GUARDED_BY(mutex_) = false; + std::mutex mutex_; + std::condition_variable cv_; + + DISALLOW_COPY_AND_ASSIGN(ConnectionWaitable); +}; + +enum class ReconnectResult { + Retry, + Success, + Abort, +}; + +#if ADB_HOST +struct usb_handle; +#endif + +class atransport : public enable_weak_from_this { + public: + // TODO(danalbert): We expose waaaaaaay too much stuff because this was + // historically just a struct, but making the whole thing a more idiomatic + // class in one go is a very large change. Given how bad our testing is, + // it's better to do this piece by piece. + + using ReconnectCallback = std::function; + + atransport(ReconnectCallback reconnect, ConnectionState state) + : id(NextTransportId()), + kicked_(false), + connection_state_(state), + connection_(nullptr), + reconnect_(std::move(reconnect)) { +#if ADB_HOST + connection_waitable_ = std::make_shared(); +#endif + + // Initialize protocol to min version for compatibility with older versions. + // Version will be updated post-connect. + protocol_version = A_VERSION_MIN; + max_payload = MAX_PAYLOAD; + } + atransport(ConnectionState state = kCsOffline) + : atransport([](atransport*) { return ReconnectResult::Abort; }, state) {} + ~atransport(); + + int Write(apacket* p); + void Reset(); + void Kick(); + bool kicked() const { return kicked_; } + + // ConnectionState can be read by all threads, but can only be written in the main thread. + ConnectionState GetConnectionState() const; + void SetConnectionState(ConnectionState state); + + void SetConnection(std::shared_ptr connection); + std::shared_ptr connection() { + std::lock_guard lock(mutex_); + return connection_; + } + + bool HandleRead(std::unique_ptr p); + void HandleError(const std::string& error); + +#if ADB_HOST + void SetUsbHandle(usb_handle* h) { usb_handle_ = h; } + usb_handle* GetUsbHandle() { return usb_handle_; } + + // Interface for management/filter on forward:reverse: configuration. + void UpdateReverseConfig(std::string_view service_addr); + bool IsReverseConfigured(const std::string& local_addr); +#endif + + const TransportId id; + + bool online = false; + TransportType type = kTransportAny; + + // Used to identify transports for clients. + std::string serial; + std::string product; + std::string model; + std::string device; + std::string devpath; + + // If this is set, the transport will initiate the connection with a + // START_TLS command, instead of AUTH. + bool use_tls = false; + int tls_version = A_STLS_VERSION; + int get_tls_version() const; + +#if !ADB_HOST + // Used to provide the key to the framework. + std::string auth_key; + std::optional auth_id; +#endif + + bool IsTcpDevice() const { return type == kTransportLocal; } + +#if ADB_HOST + // The current key being authorized. + std::shared_ptr Key(); + std::shared_ptr NextKey(); + void ResetKeys(); +#endif + + char token[TOKEN_SIZE] = {}; + size_t failed_auth_attempts = 0; + + std::string serial_name() const { return !serial.empty() ? serial : ""; } + + void update_version(int version, size_t payload); + int get_protocol_version() const; + size_t get_max_payload() const; + + const FeatureSet& features() const { return features_; } + + bool has_feature(const std::string& feature) const; + + bool SupportsDelayedAck() const { + return delayed_ack_; + } + + // Loads the transport's feature set from the given string. + void SetFeatures(const std::string& features_string); + + void AddDisconnect(adisconnect* disconnect); + void RemoveDisconnect(adisconnect* disconnect); + void RunDisconnects(); + +#if ADB_HOST + bool Attach(std::string* error); + bool Detach(std::string* error); +#endif + +#if ADB_HOST + // Returns true if |target| matches this transport. A matching |target| can be any of: + // * + // * + // * product: + // * model: + // * device: + // + // If this is a local transport, serial will also match [tcp:|udp:][:port] targets. + // For example, serial "100.100.100.100:5555" would match any of: + // * 100.100.100.100 + // * tcp:100.100.100.100 + // * udp:100.100.100.100:5555 + // This is to make it easier to use the same network target for both fastboot and adb. + bool MatchesTarget(const std::string& target) const; + + // Notifies that the atransport is no longer waiting for the connection + // being established. + void SetConnectionEstablished(bool success); + + // Gets a shared reference to the ConnectionWaitable. + std::shared_ptr connection_waitable() { return connection_waitable_; } + + // Attempts to reconnect with the underlying Connection. + ReconnectResult Reconnect(); +#endif + + private: + std::atomic kicked_; + + // A set of features transmitted in the banner with the initial connection. + // This is stored in the banner as 'features=feature0,feature1,etc'. + FeatureSet features_; + int protocol_version; + size_t max_payload; + + // A list of adisconnect callbacks called when the transport is kicked. + std::list disconnects_; + + std::atomic connection_state_; +#if ADB_HOST + std::deque> keys_; +#endif + +#if ADB_HOST + // A sharable object that can be used to wait for the atransport's + // connection to be established. + std::shared_ptr connection_waitable_; +#endif + + // The underlying connection object. + std::shared_ptr connection_ GUARDED_BY(mutex_); + +#if ADB_HOST + // USB handle for the connection, if available. + usb_handle* usb_handle_ = nullptr; +#endif + + // A callback that will be invoked when the atransport needs to reconnect. + ReconnectCallback reconnect_; + + std::mutex mutex_; + + bool delayed_ack_ = false; + +#if ADB_HOST + // Track remote addresses against local addresses (configured) + // through `adb reverse` commands. + // Access constrained to primary thread by virtue of check_main_thread(). + std::unordered_map reverse_forwards_; +#endif + + DISALLOW_COPY_AND_ASSIGN(atransport); +}; + +// --one-device command line parameter is eventually put here. +void transport_set_one_device(const char* adb_one_device); + +// Returns one device owned by this server of nullptr if all devices belong to server. +const char* transport_get_one_device(); + +// Returns true if the adb server owns all devices, or `serial`. +bool transport_server_owns_device(std::string_view serial); + +// Returns true if the adb server owns all devices, `serial`, or `dev_path`. +bool transport_server_owns_device(std::string_view dev_path, std::string_view serial); + +/* + * Obtain a transport from the available transports. + * If serial is non-null then only the device with that serial will be chosen. + * If transport_id is non-zero then only the device with that transport ID will be chosen. + * If multiple devices/emulators would match, *is_ambiguous (if non-null) + * is set to true and nullptr returned. + * If no suitable transport is found, error is set and nullptr returned. + */ +atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id, + bool* is_ambiguous, std::string* error_out, + bool accept_any_state = false); +void kick_transport(atransport* t, bool reset = false); +void update_transports(void); + +// Iterates across all of the current and pending transports. +// Stops iteration and returns false if fn returns false, otherwise returns true. +bool iterate_transports(std::function fn); + +void init_reconnect_handler(void); +void init_mdns_transport_discovery(void); + +#if ADB_HOST +atransport* find_transport(const char* serial); + +void kick_all_tcp_devices(); +#endif + +void kick_all_transports(); + +void kick_all_tcp_tls_transports(); + +#if !ADB_HOST +void kick_all_transports_by_auth_key(std::string_view auth_key); +#endif + +void register_transport(atransport* transport); + +#if ADB_HOST +void init_usb_transport(atransport* t, usb_handle* usb); + +void register_usb_transport(std::shared_ptr connection, const char* serial, + const char* devpath, unsigned writeable); +void register_usb_transport(usb_handle* h, const char* serial, const char* devpath, + unsigned writeable); + +// This should only be used for transports with connection_state == kCsNoPerm. +void unregister_usb_transport(usb_handle* usb); +#endif + +/* Connect to a network address and register it as a device */ +void connect_device(const std::string& address, std::string* response); + +/* cause new transports to be init'd and added to the list */ +bool register_socket_transport(unique_fd s, std::string serial, int port, int local, + atransport::ReconnectCallback reconnect, bool use_tls, + int* error = nullptr); + +bool check_header(apacket* p, atransport* t); + +void close_usb_devices(bool reset = false); +void close_usb_devices(std::function predicate, bool reset = false); + +void send_packet(apacket* p, atransport* t); + +#if ADB_HOST +enum TrackerOutputType { SHORT_TEXT, LONG_TEXT, PROTOBUF, TEXT_PROTOBUF }; +asocket* create_device_tracker(TrackerOutputType type); +std::string list_transports(TrackerOutputType type); +#endif + +#if !ADB_HOST +unique_fd adb_listen(std::string_view addr, std::string* error, int family); +void server_socket_thread(std::function listen_func, + std::string_view addr, int family); +#endif + +#endif /* __TRANSPORT_H */ + diff --git a/aosp/system/netd/server/InterfaceController.cpp b/aosp/system/netd/server/InterfaceController.cpp index 0cd2cd6864b3e86b8185fb5dd20c93066294a9bb..a79daf5fe432fad6ac22d0b0f76371038779789a 100644 --- a/aosp/system/netd/server/InterfaceController.cpp +++ b/aosp/system/netd/server/InterfaceController.cpp @@ -104,9 +104,7 @@ int writeValueToPath( const char* dirname, const char* subdirname, const char* basename, const char* value) { std::string path(StringPrintf("%s/%s/%s", dirname, subdirname, basename)); - // return WriteStringToFile(value, path) ? 0 : -EREMOTEIO; - ALOGV("%s, %s", path.c_str(), value); - return 0; + return WriteStringToFile(value, path) ? 0 : -EREMOTEIO; } // Run @fn on each interface as well as 'default' in the path @dirname. @@ -174,7 +172,6 @@ void setAcceptIPv6RIO(int min, int max) { forEachInterface(ipv6_proc_path, fn); } -#if 0 // Ideally this function would return StatusOr, however // there is no safe value for dflt that will always differ from the // stored property. Bugs code could conceivably end up persisting the @@ -190,7 +187,6 @@ Status setProperty(const std::string& key, const std::string& val) { ? ok : statusFromErrno(EREMOTEIO, "SetProperty failed, see libc logs"); }; -#endif } // namespace @@ -288,8 +284,7 @@ Status InterfaceController::setIPv6AddrGenMode(const std::string& interface, int writeValueToPath(ipv6_proc_path, interface.c_str(), "addr_gen_mode", "0"); break; case INetd::IPV6_ADDR_GEN_MODE_STABLE_PRIVACY: { - // return enableStablePrivacyAddresses(interface, getProperty, setProperty); - return ok; + return enableStablePrivacyAddresses(interface, getProperty, setProperty); } case INetd::IPV6_ADDR_GEN_MODE_NONE: case INetd::IPV6_ADDR_GEN_MODE_RANDOM: @@ -534,3 +529,4 @@ int InterfaceController::clearAddrs(const std::string& ifName) { } // namespace net } // namespace android + diff --git a/aosp/system/netd/server/IptablesRestoreController.cpp b/aosp/system/netd/server/IptablesRestoreController.cpp index 84d59350b8ed6cfff283c09a93891380443bdc69..5cfa86cfb8f17d5dc6f225a0601facb596850325 100644 --- a/aosp/system/netd/server/IptablesRestoreController.cpp +++ b/aosp/system/netd/server/IptablesRestoreController.cpp @@ -349,7 +349,12 @@ int IptablesRestoreController::execute(const IptablesTarget target, const std::s res |= sendCommand(IPTABLES_PROCESS, command, output); } if (target == V6 || target == V4V6) { + int resV4 = res; res |= sendCommand(IP6TABLES_PROCESS, command, output); + if (resV4 == 0 && res != 0) { + ALOGW("Ignore ip6tables command error, res: %d", res); + res = 0; + } } res = 0; return res; @@ -358,3 +363,4 @@ int IptablesRestoreController::execute(const IptablesTarget target, const std::s int IptablesRestoreController::getIpRestorePid(const IptablesProcessType type) { return type == IPTABLES_PROCESS ? mIpRestore->pid : mIp6Restore->pid; } + diff --git a/aosp/vendor/common/scripts/hook.sh b/aosp/vendor/common/scripts/hook.sh index 0cc1622e90fde9c4e8a623b20cab32142a30ae09..824645dd544a64843c3d282b3f028d4719d3f090 100644 --- a/aosp/vendor/common/scripts/hook.sh +++ b/aosp/vendor/common/scripts/hook.sh @@ -12,6 +12,13 @@ hook_net() { ifconfig wlan0 ${ip_addr}/${prefix_length} ip route add default via ${gateway_ip} dev wlan0 proto static fi + + # config IPv6 addr and route if support + if [ -n "${PHONE_IPV6_CIDR}" ] && [ -n "${BRIDGE_GATEWAY_IPV6_CIDR}" ]; then + ip -6 addr flush dev wlan0 + ip -6 addr add ${PHONE_IPV6_CIDR} dev wlan0 + ip -6 route add default via ${BRIDGE_GATEWAY_IPV6_CIDR} dev wlan0 + fi } function main() { @@ -19,4 +26,4 @@ function main() { wait } -main \ No newline at end of file +main