// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/qbone/bonnet/tun_device.h"

#include <linux/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>

#include "quic/platform/api/quic_test.h"
#include "quic/qbone/platform/mock_kernel.h"

namespace quic {
namespace {

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::Unused;

const char kDeviceName[] = "tun0";
const int kSupportedFeatures =
    IFF_TUN | IFF_TAP | IFF_MULTI_QUEUE | IFF_ONE_QUEUE | IFF_NO_PI;

// Quite a bit of EXPECT_CALL().Times(AnyNumber()).WillRepeatedly() are used to
// make sure we can correctly set common expectations and override the
// expectation with later call to EXPECT_CALL(). ON_CALL cannot be used here
// since when EPXECT_CALL overrides ON_CALL, it ignores the parameter matcher
// which results in unexpected call even if ON_CALL exists.
class TunDeviceTest : public QuicTest {
 protected:
  void SetUp() override {
    EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _))
        .Times(AnyNumber())
        .WillRepeatedly(Invoke([this](Unused, Unused, Unused) {
          EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
          return next_fd_++;
        }));
  }

  // Set the expectations for calling Init().
  void SetInitExpectations(int mtu, bool persist) {
    EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
        .Times(AnyNumber())
        .WillRepeatedly(Invoke([this](Unused, Unused) {
          EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
          return next_fd_++;
        }));
    EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
        .Times(AnyNumber())
        .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
          auto* actual_flags = reinterpret_cast<int*>(argp);
          *actual_flags = kSupportedFeatures;
          return 0;
        }));
    EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _))
        .Times(AnyNumber())
        .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
          EXPECT_EQ(IFF_TUN | IFF_MULTI_QUEUE | IFF_NO_PI, ifr->ifr_flags);
          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
          return 0;
        }));
    EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _))
        .Times(AnyNumber())
        .WillRepeatedly(Invoke([persist](Unused, Unused, void* argp) {
          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
          if (persist) {
            EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
          } else {
            EXPECT_EQ(nullptr, ifr);
          }
          return 0;
        }));
    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _))
        .Times(AnyNumber())
        .WillRepeatedly(Invoke([mtu](Unused, Unused, void* argp) {
          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
          EXPECT_EQ(mtu, ifr->ifr_mtu);
          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
          return 0;
        }));
  }

  // Expect that Up() will be called. Force the call to fail when fail == true.
  void ExpectUp(bool fail) {
    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
        .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
          EXPECT_TRUE(ifr->ifr_flags & IFF_UP);
          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
          if (fail) {
            return -1;
          } else {
            return 0;
          }
        }));
  }

  // Expect that Down() will be called *after* the interface is up. Force the
  // call to fail when fail == true.
  void ExpectDown(bool fail) {
    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
        .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
          EXPECT_FALSE(ifr->ifr_flags & IFF_UP);
          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
          if (fail) {
            return -1;
          } else {
            return 0;
          }
        }));
  }

  MockKernel mock_kernel_;
  int next_fd_ = 100;
};

// A TunTapDevice can be initialized and up
TEST_F(TunDeviceTest, BasicWorkFlow) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
  EXPECT_TRUE(tun_device.Init());
  EXPECT_GT(tun_device.GetFileDescriptor(), -1);

  ExpectUp(/* fail = */ false);
  EXPECT_TRUE(tun_device.Up());
  ExpectDown(/* fail = */ false);
}

TEST_F(TunDeviceTest, FailToOpenTunDevice) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
  EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
      .WillOnce(Return(-1));
  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
  ExpectDown(false);
}

TEST_F(TunDeviceTest, FailToCheckFeature) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
  EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _)).WillOnce(Return(-1));
  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
  ExpectDown(false);
}

TEST_F(TunDeviceTest, TooFewFeature) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
  EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
      .WillOnce(Invoke([](Unused, Unused, void* argp) {
        int* actual_features = reinterpret_cast<int*>(argp);
        *actual_features = IFF_TUN | IFF_ONE_QUEUE;
        return 0;
      }));
  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
  ExpectDown(false);
}

TEST_F(TunDeviceTest, FailToSetFlag) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
  EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _)).WillOnce(Return(-1));
  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
}

TEST_F(TunDeviceTest, FailToPersistDevice) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
  EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _)).WillOnce(Return(-1));
  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
}

TEST_F(TunDeviceTest, FailToOpenSocket) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
  EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _)).WillOnce(Return(-1));
  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
}

TEST_F(TunDeviceTest, FailToSetMtu) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
  EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _)).WillOnce(Return(-1));
  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
  EXPECT_FALSE(tun_device.Init());
  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
}

TEST_F(TunDeviceTest, FailToUp) {
  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
  EXPECT_TRUE(tun_device.Init());
  EXPECT_GT(tun_device.GetFileDescriptor(), -1);

  ExpectUp(/* fail = */ true);
  EXPECT_FALSE(tun_device.Up());
}

}  // namespace
}  // namespace quic
