/*
 * Copyright (C) 2022 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 LOG_TAG "TcUtils"

#include "tcutils/tcutils.h"

#include "logging.h"
#include "kernelversion.h"
#include "scopeguard.h"

#include <arpa/inet.h>
#include <cerrno>
#include <cstring>
#include <libgen.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/netlink.h>
#include <linux/pkt_cls.h>
#include <linux/pkt_sched.h>
#include <linux/rtnetlink.h>
#include <linux/tc_act/tc_bpf.h>
#include <net/if.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <utility>

#define BPF_FD_JUST_USE_INT
#include <BpfSyscallWrappers.h>
#undef BPF_FD_JUST_USE_INT

// The maximum length of TCA_BPF_NAME. Sync from net/sched/cls_bpf.c.
#define CLS_BPF_NAME_LEN 256

// Classifier name. See cls_bpf_ops in net/sched/cls_bpf.c.
#define CLS_BPF_KIND_NAME "bpf"

namespace android {
namespace {

/**
 * IngressPoliceFilterBuilder builds a nlmsg request equivalent to the following
 * tc command:
 *
 * tc filter add dev .. ingress prio .. protocol .. matchall \
 *     action police rate .. burst .. conform-exceed pipe/continue \
 *     action bpf object-pinned .. \
 *     drop
 */
class IngressPoliceFilterBuilder final {
  // default mtu is 2047, so the cell logarithm factor (cell_log) is 3.
  // 0x7FF >> 0x3FF x 2^1 >> 0x1FF x 2^2 >> 0xFF x 2^3
  static constexpr int RTAB_CELL_LOGARITHM = 3;
  static constexpr size_t RTAB_SIZE = 256;
  static constexpr unsigned TIME_UNITS_PER_SEC = 1000000;

  struct Request {
    nlmsghdr n;
    tcmsg t;
    struct {
      nlattr attr;
      char str[NLMSG_ALIGN(sizeof("matchall"))];
    } kind;
    struct {
      nlattr attr;
      struct {
        nlattr attr;
        struct {
          nlattr attr;
          struct {
            nlattr attr;
            char str[NLMSG_ALIGN(sizeof("police"))];
          } kind;
          struct {
            nlattr attr;
            struct {
              nlattr attr;
              struct tc_police obj;
            } police;
            struct {
              nlattr attr;
              uint32_t u32[RTAB_SIZE];
            } rtab;
            struct {
              nlattr attr;
              int32_t s32;
            } notexceedact;
          } opt;
        } act1;
        struct {
          nlattr attr;
          struct {
            nlattr attr;
            char str[NLMSG_ALIGN(sizeof("bpf"))];
          } kind;
          struct {
            nlattr attr;
            struct {
              nlattr attr;
              uint32_t u32;
            } fd;
            struct {
              nlattr attr;
              char str[NLMSG_ALIGN(CLS_BPF_NAME_LEN)];
            } name;
            struct {
              nlattr attr;
              struct tc_act_bpf obj;
            } parms;
          } opt;
        } act2;
      } acts;
    } opt;
  };

  // class members
  const unsigned mBurstInBytes;
  const char *mBpfProgPath;
  int mBpfFd;
  Request mRequest;

  static double getTickInUsec() {
    FILE *fp = fopen("/proc/net/psched", "re");
    if (!fp) {
      ALOGE("fopen(\"/proc/net/psched\"): %s", strerror(errno));
      return 0.0;
    }
    auto scopeGuard = base::make_scope_guard([fp] { fclose(fp); });

    uint32_t t2us;
    uint32_t us2t;
    uint32_t clockRes;
    const bool isError =
        fscanf(fp, "%08x%08x%08x", &t2us, &us2t, &clockRes) != 3;

    if (isError) {
      ALOGE("fscanf(/proc/net/psched, \"%%08x%%08x%%08x\"): %s",
               strerror(errno));
      return 0.0;
    }

    const double clockFactor =
        static_cast<double>(clockRes) / TIME_UNITS_PER_SEC;
    return static_cast<double>(t2us) / static_cast<double>(us2t) * clockFactor;
  }

  static inline const double kTickInUsec = getTickInUsec();

public:
  // clang-format off
  IngressPoliceFilterBuilder(int ifIndex, uint16_t prio, uint16_t proto, unsigned rateInBytesPerSec,
                      unsigned burstInBytes, const char* bpfProgPath)
      : mBurstInBytes(burstInBytes),
        mBpfProgPath(bpfProgPath),
        mBpfFd(-1),
        mRequest{
            .n = {
                .nlmsg_len = sizeof(mRequest),
                .nlmsg_type = RTM_NEWTFILTER,
                .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE,
            },
            .t = {
                .tcm_family = AF_UNSPEC,
                .tcm_ifindex = ifIndex,
                .tcm_handle = TC_H_UNSPEC,
                .tcm_parent = TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS),
                .tcm_info = (static_cast<uint32_t>(prio) << 16)
                            | static_cast<uint32_t>(htons(proto)),
            },
            .kind = {
                .attr = {
                    .nla_len = sizeof(mRequest.kind),
                    .nla_type = TCA_KIND,
                },
                .str = "matchall",
            },
            .opt = {
                .attr = {
                    .nla_len = sizeof(mRequest.opt),
                    .nla_type = TCA_OPTIONS,
                },
                .acts = {
                    .attr = {
                        .nla_len = sizeof(mRequest.opt.acts),
                        .nla_type = TCA_U32_ACT,
                    },
                    .act1 = {
                        .attr = {
                            .nla_len = sizeof(mRequest.opt.acts.act1),
                            .nla_type = 1, // action priority
                        },
                        .kind = {
                            .attr = {
                                .nla_len = sizeof(mRequest.opt.acts.act1.kind),
                                .nla_type = TCA_ACT_KIND,
                            },
                            .str = "police",
                        },
                        .opt = {
                            .attr = {
                                .nla_len = sizeof(mRequest.opt.acts.act1.opt),
                                .nla_type = TCA_ACT_OPTIONS | NLA_F_NESTED,
                            },
                            .police = {
                                .attr = {
                                    .nla_len = sizeof(mRequest.opt.acts.act1.opt.police),
                                    .nla_type = TCA_POLICE_TBF,
                                },
                                .obj = {
                                    .action = TC_ACT_PIPE,
                                    .burst = 0,
                                    .rate = {
                                        .cell_log = RTAB_CELL_LOGARITHM,
                                        .linklayer = TC_LINKLAYER_ETHERNET,
                                        .cell_align = -1,
                                        .rate = rateInBytesPerSec,
                                    },
                                },
                            },
                            .rtab = {
                                .attr = {
                                    .nla_len = sizeof(mRequest.opt.acts.act1.opt.rtab),
                                    .nla_type = TCA_POLICE_RATE,
                                },
                                .u32 = {},
                            },
                            .notexceedact = {
                                .attr = {
                                    .nla_len = sizeof(mRequest.opt.acts.act1.opt.notexceedact),
                                    .nla_type = TCA_POLICE_RESULT,
                                },
                                .s32 = TC_ACT_UNSPEC,
                            },
                        },
                    },
                    .act2 = {
                        .attr = {
                            .nla_len = sizeof(mRequest.opt.acts.act2),
                            .nla_type = 2, // action priority
                        },
                        .kind = {
                            .attr = {
                                .nla_len = sizeof(mRequest.opt.acts.act2.kind),
                                .nla_type = TCA_ACT_KIND,
                            },
                            .str = "bpf",
                        },
                        .opt = {
                            .attr = {
                                .nla_len = sizeof(mRequest.opt.acts.act2.opt),
                                .nla_type = TCA_ACT_OPTIONS | NLA_F_NESTED,
                            },
                            .fd = {
                                .attr = {
                                    .nla_len = sizeof(mRequest.opt.acts.act2.opt.fd),
                                    .nla_type = TCA_ACT_BPF_FD,
                                },
                                .u32 = 0, // set during build()
                            },
                            .name = {
                                .attr = {
                                    .nla_len = sizeof(mRequest.opt.acts.act2.opt.name),
                                    .nla_type = TCA_ACT_BPF_NAME,
                                },
                                .str = "placeholder",
                            },
                            .parms = {
                                .attr = {
                                    .nla_len = sizeof(mRequest.opt.acts.act2.opt.parms),
                                    .nla_type = TCA_ACT_BPF_PARMS,
                                },
                                .obj = {
                                    // default action to be executed when bpf prog
                                    // returns TC_ACT_UNSPEC.
                                    .action = TC_ACT_SHOT,
                                },
                            },
                        },
                    },
                },
            },
        } {
      // constructor body
  }
  // clang-format on

  ~IngressPoliceFilterBuilder() {
    // TODO: use unique_fd
    if (mBpfFd != -1) {
      close(mBpfFd);
    }
  }

  constexpr unsigned getRequestSize() const { return sizeof(Request); }

private:
  unsigned calculateXmitTime(unsigned size) {
    const uint32_t rate = mRequest.opt.acts.act1.opt.police.obj.rate.rate;
    return (static_cast<double>(size) / static_cast<double>(rate)) *
           TIME_UNITS_PER_SEC * kTickInUsec;
  }

  void initBurstRate() {
    mRequest.opt.acts.act1.opt.police.obj.burst =
        calculateXmitTime(mBurstInBytes);
  }

  // Calculates a table with 256 transmission times for different packet sizes
  // (all the way up to MTU). RTAB_CELL_LOGARITHM is used as a scaling factor.
  // In this case, MTU size is always 2048, so RTAB_CELL_LOGARITHM is always
  // 3. Therefore, this function generates the transmission times for packets
  // of size 1..256 x 2^3.
  void initRateTable() {
    for (unsigned i = 0; i < RTAB_SIZE; ++i) {
      unsigned adjustedSize = (i + 1) << RTAB_CELL_LOGARITHM;
      mRequest.opt.acts.act1.opt.rtab.u32[i] = calculateXmitTime(adjustedSize);
    }
  }

  int initBpfFd() {
    mBpfFd = bpf::retrieveProgram(mBpfProgPath);
    if (mBpfFd == -1) {
      int error = errno;
      ALOGE("retrieveProgram failed: %d", error);
      return -error;
    }

    mRequest.opt.acts.act2.opt.fd.u32 = static_cast<uint32_t>(mBpfFd);
    snprintf(mRequest.opt.acts.act2.opt.name.str,
             sizeof(mRequest.opt.acts.act2.opt.name.str), "%s:[*fsobj]",
             basename(mBpfProgPath));

    return 0;
  }

public:
  int build() {
    if (kTickInUsec == 0.0) {
      return -EINVAL;
    }

    initBurstRate();
    initRateTable();
    return initBpfFd();
  }

  const Request *getRequest() const {
    // Make sure to call build() before calling this function. Otherwise, the
    // request will be invalid.
    return &mRequest;
  }
};

const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0};
const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;

int sendAndProcessNetlinkResponse(const void *req, int len) {
  // TODO: use unique_fd instead of ScopeGuard
  int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
  if (fd == -1) {
    int error = errno;
    ALOGE("socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE): %d",
             error);
    return -error;
  }
  auto scopeGuard = base::make_scope_guard([fd] { close(fd); });

  static constexpr int on = 1;
  if (setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on))) {
    int error = errno;
    ALOGE("setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, 1): %d", error);
    return -error;
  }

  // this is needed to get valid strace netlink parsing, it allocates the pid
  if (bind(fd, (const struct sockaddr *)&KERNEL_NLADDR,
           sizeof(KERNEL_NLADDR))) {
    int error = errno;
    ALOGE("bind(fd, {AF_NETLINK, 0, 0}: %d)", error);
    return -error;
  }

  // we do not want to receive messages from anyone besides the kernel
  if (connect(fd, (const struct sockaddr *)&KERNEL_NLADDR,
              sizeof(KERNEL_NLADDR))) {
    int error = errno;
    ALOGE("connect(fd, {AF_NETLINK, 0, 0}): %d", error);
    return -error;
  }

  int rv = send(fd, req, len, 0);

  if (rv == -1) {
    int error = errno;
    ALOGE("send(fd, req, len, 0) failed: %d", error);
    return -error;
  }

  if (rv != len) {
    ALOGE("send(fd, req, len = %d, 0) returned invalid message size %d", len,
             rv);
    return -EMSGSIZE;
  }

  struct {
    nlmsghdr h;
    nlmsgerr e;
    char buf[256];
  } resp = {};

  rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC);

  if (rv == -1) {
    int error = errno;
    ALOGE("recv() failed: %d", error);
    return -error;
  }

  if (rv < (int)NLMSG_SPACE(sizeof(struct nlmsgerr))) {
    ALOGE("recv() returned short packet: %d", rv);
    return -EBADMSG;
  }

  if (resp.h.nlmsg_len != (unsigned)rv) {
    ALOGE("recv() returned invalid header length: %d != %d",
             resp.h.nlmsg_len, rv);
    return -EBADMSG;
  }

  if (resp.h.nlmsg_type != NLMSG_ERROR) {
    ALOGE("recv() did not return NLMSG_ERROR message: %d",
             resp.h.nlmsg_type);
    return -ENOMSG;
  }

  if (resp.e.error) {
    ALOGE("NLMSG_ERROR message return error: %d", resp.e.error);
  }
  return resp.e.error; // returns 0 on success
}

int hardwareAddressType(const char *interface) {
  int fd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  if (fd < 0)
    return -errno;
  auto scopeGuard = base::make_scope_guard([fd] { close(fd); });

  struct ifreq ifr = {};
  // We use strncpy() instead of strlcpy() since kernel has to be able
  // to handle non-zero terminated junk passed in by userspace anyway,
  // and this way too long interface names (more than IFNAMSIZ-1 = 15
  // characters plus terminating NULL) will not get truncated to 15
  // characters and zero-terminated and thus potentially erroneously
  // match a truncated interface if one were to exist.
  strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));

  if (ioctl(fd, SIOCGIFHWADDR, &ifr, sizeof(ifr))) {
    return -errno;
  }
  return ifr.ifr_hwaddr.sa_family;
}

} // namespace

int isEthernet(const char *iface, bool &isEthernet) {
  int rv = hardwareAddressType(iface);
  if (rv < 0) {
    ALOGE("Get hardware address type of interface %s failed: %s", iface,
             strerror(-rv));
    return rv;
  }

  // Backwards compatibility with pre-GKI kernels that use various custom
  // ARPHRD_* for their cellular interface
  switch (rv) {
  // ARPHRD_PUREIP on at least some Mediatek Android kernels
  // example: wembley with 4.19 kernel
  case 520:
  // in Linux 4.14+ rmnet support was upstreamed and ARHRD_RAWIP became 519,
  // but it is 530 on at least some Qualcomm Android 4.9 kernels with rmnet
  // example: Pixel 3 family
  case 530:
    // >5.4 kernels are GKI2.0 and thus upstream compatible, however 5.10
    // shipped with Android S, so (for safety) let's limit ourselves to
    // >5.10, ie. 5.11+ as a guarantee we're on Android T+ and thus no
    // longer need this non-upstream compatibility logic
    static bool is_pre_5_11_kernel = !isAtLeastKernelVersion(5, 11, 0);
    if (is_pre_5_11_kernel)
      return false;
  }

  switch (rv) {
  case ARPHRD_ETHER:
    isEthernet = true;
    return 0;
  case ARPHRD_NONE:
  case ARPHRD_PPP:
  case ARPHRD_RAWIP:
    isEthernet = false;
    return 0;
  default:
    ALOGE("Unknown hardware address type %d on interface %s", rv, iface);
    return -EAFNOSUPPORT;
  }
}

// ADD:     nlMsgType=RTM_NEWQDISC nlMsgFlags=NLM_F_EXCL|NLM_F_CREATE
// REPLACE: nlMsgType=RTM_NEWQDISC nlMsgFlags=NLM_F_CREATE|NLM_F_REPLACE
// DEL:     nlMsgType=RTM_DELQDISC nlMsgFlags=0
int doTcQdiscClsact(int ifIndex, uint16_t nlMsgType, uint16_t nlMsgFlags) {
  // This is the name of the qdisc we are attaching.
  // Some hoop jumping to make this compile time constant with known size,
  // so that the structure declaration is well defined at compile time.
#define CLSACT "clsact"
  // sizeof() includes the terminating NULL
  static constexpr size_t ASCIIZ_LEN_CLSACT = sizeof(CLSACT);

  const struct {
    nlmsghdr n;
    tcmsg t;
    struct {
      nlattr attr;
      char str[NLMSG_ALIGN(ASCIIZ_LEN_CLSACT)];
    } kind;
  } req = {
      .n =
          {
              .nlmsg_len = sizeof(req),
              .nlmsg_type = nlMsgType,
              .nlmsg_flags =
                  static_cast<__u16>(NETLINK_REQUEST_FLAGS | nlMsgFlags),
          },
      .t =
          {
              .tcm_family = AF_UNSPEC,
              .tcm_ifindex = ifIndex,
              .tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0),
              .tcm_parent = TC_H_CLSACT,
          },
      .kind =
          {
              .attr =
                  {
                      .nla_len = NLA_HDRLEN + ASCIIZ_LEN_CLSACT,
                      .nla_type = TCA_KIND,
                  },
              .str = CLSACT,
          },
  };
#undef CLSACT

  return sendAndProcessNetlinkResponse(&req, sizeof(req));
}

// tc filter add dev .. in/egress prio 1 protocol ipv6/ip bpf object-pinned
// /sys/fs/bpf/... direct-action
int tcAddBpfFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto,
                   const char *bpfProgPath) {
  const int bpfFd = bpf::retrieveProgram(bpfProgPath);
  if (bpfFd == -1) {
    ALOGE("retrieveProgram failed: %d", errno);
    return -errno;
  }
  auto scopeGuard = base::make_scope_guard([bpfFd] { close(bpfFd); });

  struct {
    nlmsghdr n;
    tcmsg t;
    struct {
      nlattr attr;
      // The maximum classifier name length is defined in
      // tcf_proto_ops in include/net/sch_generic.h.
      char str[NLMSG_ALIGN(sizeof(CLS_BPF_KIND_NAME))];
    } kind;
    struct {
      nlattr attr;
      struct {
        nlattr attr;
        __u32 u32;
      } fd;
      struct {
        nlattr attr;
        char str[NLMSG_ALIGN(CLS_BPF_NAME_LEN)];
      } name;
      struct {
        nlattr attr;
        __u32 u32;
      } flags;
    } options;
  } req = {
      .n =
          {
              .nlmsg_len = sizeof(req),
              .nlmsg_type = RTM_NEWTFILTER,
              .nlmsg_flags = NETLINK_REQUEST_FLAGS | NLM_F_EXCL | NLM_F_CREATE,
          },
      .t =
          {
              .tcm_family = AF_UNSPEC,
              .tcm_ifindex = ifIndex,
              .tcm_handle = TC_H_UNSPEC,
              .tcm_parent = TC_H_MAKE(TC_H_CLSACT, ingress ? TC_H_MIN_INGRESS
                                                           : TC_H_MIN_EGRESS),
              .tcm_info =
                  static_cast<__u32>((static_cast<uint16_t>(prio) << 16) |
                                     htons(static_cast<uint16_t>(proto))),
          },
      .kind =
          {
              .attr =
                  {
                      .nla_len = sizeof(req.kind),
                      .nla_type = TCA_KIND,
                  },
              .str = CLS_BPF_KIND_NAME,
          },
      .options =
          {
              .attr =
                  {
                      .nla_len = sizeof(req.options),
                      .nla_type = NLA_F_NESTED | TCA_OPTIONS,
                  },
              .fd =
                  {
                      .attr =
                          {
                              .nla_len = sizeof(req.options.fd),
                              .nla_type = TCA_BPF_FD,
                          },
                      .u32 = static_cast<__u32>(bpfFd),
                  },
              .name =
                  {
                      .attr =
                          {
                              .nla_len = sizeof(req.options.name),
                              .nla_type = TCA_BPF_NAME,
                          },
                      // Visible via 'tc filter show', but
                      // is overwritten by strncpy below
                      .str = "placeholder",
                  },
              .flags =
                  {
                      .attr =
                          {
                              .nla_len = sizeof(req.options.flags),
                              .nla_type = TCA_BPF_FLAGS,
                          },
                      .u32 = TCA_BPF_FLAG_ACT_DIRECT,
                  },
          },
  };

  snprintf(req.options.name.str, sizeof(req.options.name.str), "%s:[*fsobj]",
           basename(bpfProgPath));

  int error = sendAndProcessNetlinkResponse(&req, sizeof(req));
  return error;
}

// tc filter add dev .. ingress prio .. protocol .. matchall \
//     action police rate .. burst .. conform-exceed pipe/continue \
//     action bpf object-pinned .. \
//     drop
//
// TODO: tc-police does not do ECN marking, so in the future, we should consider
// adding a second tc-police filter at a lower priority that rate limits traffic
// at something like 0.8 times the global rate limit and ecn marks exceeding
// packets inside a bpf program (but does not drop them).
int tcAddIngressPoliceFilter(int ifIndex, uint16_t prio, uint16_t proto,
                             unsigned rateInBytesPerSec,
                             const char *bpfProgPath) {
  // TODO: this value needs to be validated.
  // TCP IW10 (initial congestion window) means servers will send 10 mtus worth
  // of data on initial connect.
  // If nic is LRO capable it could aggregate up to 64KiB, so again probably a
  // bad idea to set burst below that, because ingress packets could get
  // aggregated to 64KiB at the nic.
  // I don't know, but I wonder whether we shouldn't just do 128KiB and not do
  // any math.
  static constexpr unsigned BURST_SIZE_IN_BYTES = 128 * 1024; // 128KiB
  IngressPoliceFilterBuilder filter(ifIndex, prio, proto, rateInBytesPerSec,
                                    BURST_SIZE_IN_BYTES, bpfProgPath);
  const int error = filter.build();
  if (error) {
    return error;
  }
  return sendAndProcessNetlinkResponse(filter.getRequest(),
                                       filter.getRequestSize());
}

// tc filter del dev .. in/egress prio .. protocol ..
int tcDeleteFilter(int ifIndex, bool ingress, uint16_t prio, uint16_t proto) {
  const struct {
    nlmsghdr n;
    tcmsg t;
  } req = {
      .n =
          {
              .nlmsg_len = sizeof(req),
              .nlmsg_type = RTM_DELTFILTER,
              .nlmsg_flags = NETLINK_REQUEST_FLAGS,
          },
      .t =
          {
              .tcm_family = AF_UNSPEC,
              .tcm_ifindex = ifIndex,
              .tcm_handle = TC_H_UNSPEC,
              .tcm_parent = TC_H_MAKE(TC_H_CLSACT, ingress ? TC_H_MIN_INGRESS
                                                           : TC_H_MIN_EGRESS),
              .tcm_info =
                  static_cast<__u32>((static_cast<uint16_t>(prio) << 16) |
                                     htons(static_cast<uint16_t>(proto))),
          },
  };

  return sendAndProcessNetlinkResponse(&req, sizeof(req));
}

} // namespace android
