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

#ifndef PATCHPANEL_NETWORK_MONITOR_SERVICE_H_
#define PATCHPANEL_NETWORK_MONITOR_SERVICE_H_

#include <map>
#include <memory>
#include <linux/neighbour.h>
#include <set>
#include <string>
#include <vector>

#include <base/memory/weak_ptr.h>
#include <base/timer/timer.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "patchpanel/shill_client.h"
#include "shill/net/ip_address.h"
#include "shill/net/rtnl_listener.h"
#include "shill/net/rtnl_message.h"

namespace patchpanel {

// Monitors the reachability to the gateway and DNS servers on a given interface
// based on the information from the neighbor table in Linux kernel.
//
// This class interacts with the neighbor table via rtnetlink messages. The NUD
// (Neighbour Unreachability Detection) state in the neighbor table shows the
// bidirectional reachability between this interface and the given address. When
// OnIPConfigChanged() is called, a watching list is created with all valid
// addresses ({gateway, local dns servers} x {ipv4, ipv6}) in this ipconfig. For
// each address in the watching list, this class will:
// - Listen to the NUD state changed event from kernel;
// - When applicable, periodically set NUD state into NUD_PROBE to make the
// kernel send probe packets.
//
// Normally, the following events will happen after an address is added:
// 1) We (this class) send a RTM_GETNEIGH request to the kernel to get the
//    current state of this address;
// 2) On receiving the response from the kernel, we send a RTM_NEWNEIGH request
//    at once to set the NUD state of this address into NUD_PROBE, when
//    applicable;
// 3) The kernel sends out an ARP request (IPv4) or NS (IPv6) packet to this
//    address, and we are notified that the NUD state in the kernel table is
//    changed to NUD_PROBE.
// 4) The kernel receives the response packet and changes the state into
//    NUD_REACHABLE and notifies us.
// 5) Do nothing until the timer is triggered, and then jump to Step 2.
//
// In the case of "failure":
// - If we fail to get the information in Step 1, when the timer is triggered,
//   we will try to send the RTM_GETNEIGH request again (jump to Step 1).
// - If the kernel fails to detect the reachability in Step 3 (i.e., several
//   timeouts happen), we will be notified that the state is changed to
//   NUD_FAILED. Then we will do nothing for this address, until we heard about
//   it again from kernel.
class NeighborLinkMonitor {
 public:
  NeighborLinkMonitor(int ifindex,
                      const std::string& ifname,
                      shill::RTNLHandler* rtnl_handler);
  ~NeighborLinkMonitor() = default;

  NeighborLinkMonitor(const NeighborLinkMonitor&) = delete;
  NeighborLinkMonitor& operator=(const NeighborLinkMonitor&) = delete;

  // Resets |watching_entries_| with addresses in |ipconfig|, calls
  // Start()/Stop() depends on whether the new |watching_entries_| is not empty.
  void OnIPConfigChanged(const ShillClient::IPConfig& ipconfig);

 private:
  // Represents an address and its corresponding role (a gateway or dns server
  // or both) we are watching. Also tracks the NUD state of this address in the
  // kernel.
  struct WatchingEntry {
    enum class Role {
      kGateway = 0x1,
      kDNSServer = 0x2,
    };

    WatchingEntry(shill::IPAddress addr, Role role);
    std::string ToString() const;

    shill::IPAddress addr;
    // Since an address could have different rules at the same time, we use a
    // bitmap to represent its roles.
    uint8_t role_flags;
    // Reflects the NUD state of |addr| in the kernel neighbor table. Notes that
    // we use NUD_NONE (which is a dummy state in the kernel) to indicate that
    // we don't know this address from the kernel (i.e., this entry is just
    // added or the kernel tells us this entry has been deleted). If an entry is
    // in this state, we will send a get request to the kernel when the timer is
    // triggered.
    uint16_t nud_state = NUD_NONE;
  };

  // For each entry in |watching_entries_|, sends a RTM_NEWNEIGH message to set
  // the NUD state in the kernel to NUD_PROBE, or sends a RTM_GETNEIGH message
  // if we haven't heard of this address from kernel.
  void ProbeAll();

  // Start() will run ProbeAll() at once and set a repeating timer to run it
  // periodically, until Stop() is called.
  void Start();
  void Stop();

  void AddWatchingEntries(int prefix_length,
                          const std::string& addr,
                          const std::string& gateway,
                          const std::vector<std::string>& dns_addresses);

  // Creates a new entry if not exist or updates the role of an existing entry.
  void UpdateWatchingEntry(const shill::IPAddress& addr,
                           WatchingEntry::Role role);

  void SendNeighborGetRTNLMessage(const WatchingEntry& entry);
  void SendNeighborProbeRTNLMessage(const WatchingEntry& entry);
  void OnNeighborMessage(const shill::RTNLMessage& msg);

  int ifindex_;
  const std::string ifname_;
  std::map<shill::IPAddress, WatchingEntry> watching_entries_;
  std::unique_ptr<shill::RTNLListener> listener_;

  // Timer for running ProbeAll().
  std::unique_ptr<base::RepeatingTimer> probe_timer_;

  // RTNLHandler is a singleton object. Stores it here for test purpose.
  shill::RTNLHandler* rtnl_handler_;

  FRIEND_TEST(NeighborLinkMonitorTest, SendNeighborGetMessageOnIPConfigChanged);
  FRIEND_TEST(NeighborLinkMonitorTest, WatchLinkLocalIPv6DNSServerAddress);
  FRIEND_TEST(NeighborLinkMonitorTest, SendNeighborProbeMessage);
};

class NetworkMonitorService {
 public:
  explicit NetworkMonitorService(ShillClient* shill_client);
  ~NetworkMonitorService() = default;

  NetworkMonitorService(const NetworkMonitorService&) = delete;
  NetworkMonitorService& operator=(const NetworkMonitorService&) = delete;

  void Start();

 private:
  void OnDevicesChanged(const std::set<std::string>& added,
                        const std::set<std::string>& removed);
  void OnIPConfigsChanged(const std::string& device,
                          const ShillClient::IPConfig& ipconfig);

  // ifname => NeighborLinkMonitor.
  std::map<std::string, std::unique_ptr<NeighborLinkMonitor>>
      neighbor_link_monitors_;
  ShillClient* shill_client_;
  // RTNLHandler is a singleton object. Stores it here for test purpose.
  shill::RTNLHandler* rtnl_handler_;

  FRIEND_TEST(NetworkMonitorServiceTest, StartRTNLHanlderOnServiceStart);
  FRIEND_TEST(NetworkMonitorServiceTest, CallGetDevicePropertiesOnNewDevice);

  base::WeakPtrFactory<NetworkMonitorService> weak_factory_{this};
};

}  // namespace patchpanel

#endif  // PATCHPANEL_NETWORK_MONITOR_SERVICE_H_
