108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz/* 208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * Copyright (C) 2017 The Android Open Source Project 308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * 408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * Licensed under the Apache License, Version 2.0 (the "License"); 508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * you may not use this file except in compliance with the License. 608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * You may obtain a copy of the License at 708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * 808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * http://www.apache.org/licenses/LICENSE-2.0 908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * 1008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * Unless required by applicable law or agreed to in writing, software 1108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * distributed under the License is distributed on an "AS IS" BASIS, 1208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * See the License for the specific language governing permissions and 1408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz * limitations under the License. 1508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz */ 1608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 1708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#define LOG_TAG "WakeupController" 1808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 19e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <arpa/inet.h> 20e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <iostream> 2108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include <linux/netfilter/nfnetlink.h> 2208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include <linux/netfilter/nfnetlink_log.h> 23e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <sys/socket.h> 24e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <netinet/if_ether.h> 25e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <netinet/in.h> 26e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <netinet/ip.h> 27e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <netinet/ip6.h> 28e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <netinet/tcp.h> 29e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <netinet/udp.h> 3008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 31e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi#include <android-base/strings.h> 3208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include <android-base/stringprintf.h> 3308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include <cutils/log.h> 3408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include <netdutils/Netfilter.h> 3508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include <netdutils/Netlink.h> 3608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 3708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include "IptablesRestoreController.h" 3808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include "NetlinkManager.h" 3908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz#include "WakeupController.h" 4008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 4108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelznamespace android { 4208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelznamespace net { 4308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 4408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelzusing base::StringPrintf; 4508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelzusing netdutils::Slice; 4608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelzusing netdutils::Status; 4708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 4808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelzconst char WakeupController::LOCAL_MANGLE_INPUT[] = "wakeupctrl_mangle_INPUT"; 4908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 50e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichiconst uint32_t WakeupController::kDefaultPacketCopyRange = 51e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi sizeof(struct tcphdr) + sizeof(struct ip6_hdr); 52e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi 53e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichistatic void extractIpPorts(WakeupController::ReportArgs& args, Slice payload) { 54e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi switch (args.ipNextHeader) { 55e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case IPPROTO_TCP: { 56e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct tcphdr header; 57e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi if (extract(payload, header) < sizeof(struct tcphdr)) { 58e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi return; 59e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 60e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.srcPort = ntohs(header.th_sport); 61e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.dstPort = ntohs(header.th_dport); 62e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 63e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 64e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case IPPROTO_UDP: { 65e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct udphdr header; 66e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi if (extract(payload, header) < sizeof(struct udphdr)) { 67e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi return; 68e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 69e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.srcPort = ntohs(header.uh_sport); 70e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.dstPort = ntohs(header.uh_dport); 71e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 72e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 73e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi default: 74e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 75e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 76e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi} 77e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi 78e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichistatic void extractIpHeader(WakeupController::ReportArgs& args, Slice payload) { 79e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi switch (args.ethertype) { 80e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case ETH_P_IP: { 81e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct iphdr header; 82e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi if (extract(payload, header) < sizeof(struct iphdr)) { 83e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi return; 84e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 85e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.ipNextHeader = header.protocol; 86e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi char addr[INET_ADDRSTRLEN] = {}; 87e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi inet_ntop(AF_INET, &header.saddr, addr, sizeof(addr)); 88e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.srcIp = addr; 89e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi inet_ntop(AF_INET, &header.daddr, addr, sizeof(addr)); 90e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.dstIp = addr; 91e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extractIpPorts(args, drop(payload, header.ihl * 4)); // ipv4 IHL counts 32 bit words. 92e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 93e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 94e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case ETH_P_IPV6: { 95e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct ip6_hdr header; 96e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi if (extract(payload, header) < sizeof(struct ip6_hdr)) { 97e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi return; 98e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 99e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.ipNextHeader = header.ip6_nxt; 100e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi char addr[INET6_ADDRSTRLEN] = {}; 101e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi inet_ntop(AF_INET6, &header.ip6_src, addr, sizeof(addr)); 102e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.srcIp = addr; 103e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi inet_ntop(AF_INET6, &header.ip6_dst, addr, sizeof(addr)); 104e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.dstIp = addr; 105e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // TODO: also deal with extension headers 106e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi if (args.ipNextHeader == IPPROTO_TCP || args.ipNextHeader == IPPROTO_UDP) { 107e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extractIpPorts(args, drop(payload, sizeof(header))); 108e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 109e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 110e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 111e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi default: 112e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 113e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 114e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi} 115e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi 11608b84cd0d223ae3059ce7d4d55b389fdea187580Joel ScherpelzWakeupController::~WakeupController() { 11708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz expectOk(mListener->unsubscribe(NetlinkManager::NFLOG_WAKEUP_GROUP)); 11808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} 11908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 12008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelznetdutils::Status WakeupController::init(NFLogListenerInterface* listener) { 12108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz mListener = listener; 12208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz const auto msgHandler = [this](const nlmsghdr&, const nfgenmsg&, const Slice msg) { 123e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi 124e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct WakeupController::ReportArgs args = { 125e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi .uid = -1, 126e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi .gid = -1, 127e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi .ethertype = -1, 128e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi .ipNextHeader = -1, 129e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi .srcPort = -1, 130e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi .dstPort = -1, 131e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // and all other fields set to 0 as the default 132e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi }; 133e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi bool parseAgain = false; 134e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi 135e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi const auto attrHandler = [&args, &parseAgain](const nlattr attr, const Slice payload) { 13608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz switch (attr.nla_type) { 13708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz case NFULA_TIMESTAMP: { 1385a73b949b859cff86b838c0fd467894ee88820f9Hugo Benichi timespec ts = {}; 1395a73b949b859cff86b838c0fd467894ee88820f9Hugo Benichi extract(payload, ts); 14008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz constexpr uint64_t kNsPerS = 1000000000ULL; 141e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.timestampNs = ntohl(ts.tv_nsec) + (ntohl(ts.tv_sec) * kNsPerS); 14208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz break; 14308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz } 14408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz case NFULA_PREFIX: 14508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz // Strip trailing '\0' 146e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.prefix = toString(take(payload, payload.size() - 1)); 14708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz break; 14808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz case NFULA_UID: 149e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extract(payload, args.uid); 150e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.uid = ntohl(args.uid); 15108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz break; 15208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz case NFULA_GID: 153e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extract(payload, args.gid); 154e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.gid = ntohl(args.gid); 155e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 156e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case NFULA_HWADDR: { 157e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct nfulnl_msg_packet_hw hwaddr = {}; 158e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extract(payload, hwaddr); 159e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi size_t hwAddrLen = ntohs(hwaddr.hw_addrlen); 160e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi hwAddrLen = std::min(hwAddrLen, sizeof(hwaddr.hw_addr)); 161e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.dstHw.assign(hwaddr.hw_addr, hwaddr.hw_addr + hwAddrLen); 162e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 163e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 164e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case NFULA_PACKET_HDR: { 165e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi struct nfulnl_msg_packet_hdr packetHdr = {}; 166e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extract(payload, packetHdr); 167e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi args.ethertype = ntohs(packetHdr.hw_protocol); 168e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi break; 169e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 170e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi case NFULA_PAYLOAD: 171e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // The packet payload is expected to come last in the Netlink message. 172e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // At that point NFULA_PACKET_HDR has already been parsed and processed. 173e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // If this is not the case, set parseAgain to true. 174e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi parseAgain = (args.ethertype == -1); 175e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi extractIpHeader(args, payload); 17608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz break; 17708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz default: 17808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz break; 17908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz } 18008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz }; 181e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi 18208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz forEachNetlinkAttribute(msg, attrHandler); 183e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi if (parseAgain) { 184e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // NFULA_PAYLOAD was parsed before NFULA_PACKET_HDR. 185e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi // Now that the ethertype is known, reparse msg for correctly extracting the payload. 186e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi forEachNetlinkAttribute(msg, attrHandler); 187e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi } 188e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi mReport(args); 18908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz }; 190e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi return mListener->subscribe(NetlinkManager::NFLOG_WAKEUP_GROUP, 191e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi WakeupController::kDefaultPacketCopyRange, msgHandler); 19208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} 19308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 19408b84cd0d223ae3059ce7d4d55b389fdea187580Joel ScherpelzStatus WakeupController::addInterface(const std::string& ifName, const std::string& prefix, 19508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz uint32_t mark, uint32_t mask) { 19608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz return execIptables("-A", ifName, prefix, mark, mask); 19708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} 19808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 19908b84cd0d223ae3059ce7d4d55b389fdea187580Joel ScherpelzStatus WakeupController::delInterface(const std::string& ifName, const std::string& prefix, 20008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz uint32_t mark, uint32_t mask) { 20108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz return execIptables("-D", ifName, prefix, mark, mask); 20208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} 20308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 20408b84cd0d223ae3059ce7d4d55b389fdea187580Joel ScherpelzStatus WakeupController::execIptables(const std::string& action, const std::string& ifName, 20508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz const std::string& prefix, uint32_t mark, uint32_t mask) { 20608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz // NFLOG messages to batch before releasing to userspace 20708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz constexpr int kBatch = 8; 20808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz // Max log message rate in packets/second 20908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz constexpr int kRateLimit = 10; 21008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz const char kFormat[] = 21108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz "*mangle\n%s %s -i %s -j NFLOG --nflog-prefix %s --nflog-group %d --nflog-threshold %d" 21277660392eb3e9aa287cc02307c443ee64b5fc570Hugo Benichi " -m mark --mark 0x%08x/0x%08x -m limit --limit %d/s\nCOMMIT\n"; 21308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz const auto cmd = StringPrintf( 214e874b7f00ce5bd34a750ed1eb021f50679c6535dHugo Benichi kFormat, action.c_str(), WakeupController::LOCAL_MANGLE_INPUT, ifName.c_str(), 21577660392eb3e9aa287cc02307c443ee64b5fc570Hugo Benichi prefix.c_str(), NetlinkManager::NFLOG_WAKEUP_GROUP, kBatch, mark, mask, kRateLimit); 21608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 21708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz std::string out; 21808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz auto rv = mIptables->execute(V4V6, cmd, &out); 21908b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz if (rv != 0) { 22008b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz auto s = Status(rv, "Failed to execute iptables cmd: " + cmd + ", out: " + out); 22108b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz ALOGE("%s", toString(s).c_str()); 22208b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz return s; 22308b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz } 22408b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz return netdutils::status::ok; 22508b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} 22608b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz 22708b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} // namespace net 22808b84cd0d223ae3059ce7d4d55b389fdea187580Joel Scherpelz} // namespace android 229