blob: d011d0a8b7b795e8416795445ba4485741df5991 [file] [log] [blame]
// 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.
#ifndef PORTIER_NEIGHBOR_CACHE_H_
#define PORTIER_NEIGHBOR_CACHE_H_
#include <map>
#include <string>
#include <utility>
#include <vector>
#include <shill/net/ip_address.h>
#include "portier/ll_address.h"
namespace portier {
// A subset of the Linux struct neighbour containing only the IPv6 relevant
// information about neighbors.
struct NeighborCacheEntry {
shill::IPAddress ip_address;
LLAddress ll_address;
std::string if_name;
bool is_router;
uint8_t nud_state;
NeighborCacheEntry();
~NeighborCacheEntry() = default;
};
// Manages the cache of neighbour enteries. Each entry is keyed by
// its IPv6 address and a group name. The neighbor cache does not
// validate the normal rules of proxy group memberships.
// This class is not thread safe and is intended to run a single threaded
// event loop.
class NeighborCache {
public:
NeighborCache() {}
~NeighborCache() = default;
// Get the neighbor cache entry that is associated to the given
// |ip_address| and |pg_name|. Returns false if there is no entry
// associated to that IP address-group name pair.
bool GetEntry(const shill::IPAddress& ip_address,
const std::string& pg_name,
NeighborCacheEntry* entry_out) const;
// Get the best router neighbor entry for the provided |if_name|,
// |pg_name| pair. The determination of what is "best" is based on
// the ranking of the NUD state of the cache entry. In increasing
// order of priority (defined in RFC4389): INCOMPLETE, STALE, DELAY,
// PROBE, REACHABLE. Routers in a FAILED state are not returned.
bool GetInterfaceRouter(const std::string& if_name,
const std::string& pg_name,
NeighborCacheEntry* entry_out) const;
// Returns true if there exists and entry associated to the given
// |ip_address| and |pg_name| pair.
bool HasEntry(const shill::IPAddress& ip_address,
const std::string& pg_name) const;
// Inserts a new neighbor cache entry, replacing any entry already
// associated to specified IP address and group name pair.
// Call will fail if:
// - |pg_name| is empty.
// - |entry.ip_address| is not IPv6.
// - |entry.ll_address| is invalid.
// - |entry.if_name| is empty.
// - |entry.nud_state| is not one of the Linux recognized states.
bool InsertEntry(const std::string& pg_name, const NeighborCacheEntry& entry);
// Clear the specific entry assocated to the provided |ip_address|.
void RemoveEntry(const shill::IPAddress& ip_address,
const std::string& pg_name);
// Removes all of the neighbor cache entries associated to a
// specified interface name. Useful if an interface is destroyed
// or removed from a group.
void ClearForInterface(const std::string& if_name);
// Removes all of the neighbor cache entries associated to a
// specified group name. Useful if a group is destroyed.
void ClearForGroup(const std::string& pg_name);
// Clears out the entire cache.
void Clear();
private:
// Maps the pair of the string representation of the IPv6 address
// and the group name to a neighbor cache entry.
std::map<std::pair<shill::IPAddress, std::string>, NeighborCacheEntry>
entries_;
};
} // namespace portier
#endif // PORTIER_NEIGHBOR_CACHE_H_