fboss/agent/state/NeighborTable.h (79 lines of code) (raw):

/* * Copyright (c) 2004-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #pragma once #include <folly/MacAddress.h> #include <folly/dynamic.h> #include <folly/json.h> #include "fboss/agent/state/NeighborEntry.h" #include "fboss/agent/state/NodeMap.h" #include "fboss/agent/state/PortDescriptor.h" namespace facebook::fboss { class SwitchState; class Vlan; template <typename IPADDR, typename ENTRY> struct NeighborTableTraits { using KeyType = IPADDR; using Node = ENTRY; using ExtraFields = NodeMapNoExtraFields; using NodeContainer = boost::container::flat_map<KeyType, std::shared_ptr<Node>>; static KeyType getKey(const std::shared_ptr<Node>& entry) { return entry->getIP(); } }; template <typename IPADDR, typename ENTRY> struct NeighborTableThriftTraits : public ThriftyNodeMapTraits<std::string, state::NeighborEntryFields> { static inline const std::string& getThriftKeyName() { static const std::string _key = "ipaddress"; return _key; } static const KeyType convertKey(const IPADDR& key) { return key.str(); } static const KeyType parseKey(const folly::dynamic& key) { return key.asString(); } }; /* * A map of IP --> MAC for the IP addresses of other nodes on a VLAN. * * TODO: We should switch from NodeMap to PrefixMap when the new PrefixMap * implementation is ready. * * Any change to a NodeMap is O(N), so it is really only suitable for small * maps that do not change frequently. Our new PrefixMap implementation will * allow us to perform cheaper copy-on-write updates. */ template <typename IPADDR, typename ENTRY, typename SUBCLASS> class NeighborTable : public ThriftyNodeMapT< SUBCLASS, NeighborTableTraits<IPADDR, ENTRY>, NeighborTableThriftTraits<IPADDR, ENTRY>> { public: typedef IPADDR AddressType; typedef ENTRY Entry; NeighborTable(); const std::shared_ptr<Entry>& getEntry(AddressType ip) const { return this->getNode(ip); } std::shared_ptr<Entry> getEntryIf(AddressType ip) const { return this->getNodeIf(ip); } SUBCLASS* modify(Vlan** vlan, std::shared_ptr<SwitchState>* state); /** * Return a modifiable version of current table. If the table is cloned, all * nodes to the root are cloned, and cloned state is put in the output * parameter. */ SUBCLASS* modify(VlanID vlanId, std::shared_ptr<SwitchState>* state); void addEntry( AddressType ip, folly::MacAddress mac, PortDescriptor port, InterfaceID intfID, NeighborState state = NeighborState::REACHABLE); void addEntry(const NeighborEntryFields<AddressType>& fields); void updateEntry( AddressType ip, folly::MacAddress mac, PortDescriptor port, InterfaceID intfID, std::optional<cfg::AclLookupClass> classID = std::nullopt); void updateEntry(const NeighborEntryFields<AddressType>& fields); void updateEntry(AddressType ip, std::shared_ptr<ENTRY>); void addPendingEntry(AddressType ip, InterfaceID intfID); void removeEntry(AddressType ip); private: typedef ThriftyNodeMapT< SUBCLASS, NeighborTableTraits<IPADDR, ENTRY>, NeighborTableThriftTraits<IPADDR, ENTRY>> Parent; // Inherit the constructors required for clone() using Parent::Parent; friend class CloneAllocator; }; } // namespace facebook::fboss