// Copyright 2018 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.

#include "portier/neighbor_cache.h"

#include <linux/neighbour.h>

#include <utility>

#include <base/logging.h>
#include <base/stl_util.h>

namespace portier {

using std::string;
using std::vector;

using shill::IPAddress;

using KeyPair = std::pair<const IPAddress, const string>;
using NeighPair = std::pair<KeyPair, NeighborCacheEntry>;

namespace {

// Checks if the specified |nud_state| is one of the valid NUD states
// recognized by the Linux kernel.  These states are specified in
// <linux/neighbour.h>.  Note that dummy states are not recognized
// as valid.
bool IsValidNudState(uint8_t nud_state) {
  switch (nud_state) {
    case NUD_REACHABLE:
    case NUD_PROBE:
    case NUD_DELAY:
    case NUD_STALE:
    case NUD_INCOMPLETE:
    case NUD_FAILED:
      return true;
  }
  return false;
}

// Converts a NUD state into a relative score used for ranking the
// entries.  The higher the score, the high priority that NUD state
// has when multiple entries can be used.  This score is based on the
// order of preferred states in RFC 4389 Section 4.1.
int GetNudScore(uint8_t nud_state) {
  switch (nud_state) {
    case NUD_REACHABLE:
      return 5;
    case NUD_PROBE:
      return 4;
    case NUD_DELAY:
      return 3;
    case NUD_STALE:
      return 2;
    case NUD_INCOMPLETE:
      return 1;
    case NUD_FAILED:
      return 0;
  }
  return -1;
}

}  // namespace

NeighborCacheEntry::NeighborCacheEntry()
    : is_router(false), nud_state(NUD_NONE) {}

bool NeighborCache::GetEntry(const IPAddress& ip_address,
                             const string& pg_name,
                             NeighborCacheEntry* entry_out) const {
  DCHECK(entry_out);
  auto it = entries_.find(KeyPair(ip_address, pg_name));
  if (it != entries_.end()) {
    *entry_out = it->second;
    return true;
  }
  return false;
}

bool NeighborCache::GetInterfaceRouter(const std::string& if_name,
                                       const std::string& pg_name,
                                       NeighborCacheEntry* entry_out) const {
  DCHECK(entry_out);
  // Using an initial score of 0 to prevent routers in a FAILED states from
  // being returned.
  int nud_score = 0;
  for (const auto& pair : entries_) {
    // Check if potential match, skip if not.
    if (!pair.second.is_router || pair.second.if_name != if_name ||
        pair.first.second != pg_name) {
      continue;
    }
    int new_nud_score = GetNudScore(pair.second.nud_state);
    if (new_nud_score > nud_score) {
      nud_score = new_nud_score;
      *entry_out = pair.second;
    }
  }
  return nud_score > 0;
}

bool NeighborCache::HasEntry(const IPAddress& ip_address,
                             const string& pg_name) const {
  const KeyPair key(ip_address, pg_name);
  return base::ContainsKey(entries_, key);
}

bool NeighborCache::InsertEntry(const std::string& pg_name,
                                const NeighborCacheEntry& entry) {
  // Validating based on needs of IPv6 ND Proxying.
  if (!entry.ip_address.IsValid() ||
      entry.ip_address.family() != IPAddress::kFamilyIPv6 ||
      !entry.ll_address.IsValid() || entry.if_name.size() == 0 ||
      pg_name.size() == 0 || !IsValidNudState(entry.nud_state)) {
    return false;
  }
  const KeyPair key(entry.ip_address, pg_name);
  entries_[key] = entry;
  return true;
}

void NeighborCache::RemoveEntry(const IPAddress& ip_address,
                                const string& pg_name) {
  entries_.erase(KeyPair(ip_address, pg_name));
}

void NeighborCache::ClearForInterface(const string& if_name) {
  for (auto it = entries_.begin(); it != entries_.end();) {
    if (it->second.if_name == if_name) {
      it = entries_.erase(it);
    } else {
      ++it;
    }
  }
}

void NeighborCache::ClearForGroup(const string& pg_name) {
  for (auto it = entries_.begin(); it != entries_.end();) {
    if (it->first.second == pg_name) {
      it = entries_.erase(it);
    } else {
      ++it;
    }
  }
}

void NeighborCache::Clear() {
  entries_.clear();
}

}  // namespace portier
