LCOV - code coverage report
Current view: top level - vnsw/agent/oper - peer.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 31 39 79.5 %
Date: 2026-11-09 02:10:49 Functions: 29 35 82.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef vnsw_agent_peer_h_
       7             : #define vnsw_agent_peer_h_
       8             : 
       9             : #include <atomic>
      10             : #include <string>
      11             : #include <map>
      12             : #include <db/db_table_walker.h>
      13             : #include <base/address.h>
      14             : #include <boost/intrusive_ptr.hpp>
      15             : #include <oper/agent_route_walker.h>
      16             : 
      17             : #define LOCAL_PEER_NAME "Local"
      18             : #define LOCAL_VM_PEER_NAME "Local_Vm"
      19             : #define LOCAL_VM_PORT_PEER_NAME "LocalVmPort"
      20             : #define NOVA_PEER_NAME "Nova"
      21             : #define LINKLOCAL_PEER_NAME "LinkLocal"
      22             : #define ECMP_PEER_NAME "Ecmp"
      23             : #define VGW_PEER_NAME "Vgw"
      24             : #define EVPN_ROUTING_PEER_NAME "EVPN Router"
      25             : #define EVPN_PEER_NAME "EVPN"
      26             : #define MULTICAST_PEER_NAME "Multicast"
      27             : #define MULTICAST_TOR_PEER_NAME "Multicast TOR"
      28             : #define MULTICAST_FABRIC_TREE_BUILDER_NAME "MulticastTreeBuilder"
      29             : #define MAC_VM_BINDING_PEER_NAME "MacVmBindingPeer"
      30             : #define MAC_LEARNING_PEER_NAME "DynamicMacLearningPeer"
      31             : #define FABRIC_RT_EXPORT "FabricRouteExport"
      32             : #define LOCAL_VM_EXPORT_PEER "LocalVmExportPeer"
      33             : 
      34             : class AgentXmppChannel;
      35             : class ControllerRouteWalker;
      36             : class VrfTable;
      37             : class AgentPath;
      38             : 
      39             : class Peer;
      40             : void intrusive_ptr_add_ref(const Peer* p);
      41             : void intrusive_ptr_release(const Peer* p);
      42             : typedef boost::intrusive_ptr<const Peer> PeerConstPtr;
      43             : typedef boost::intrusive_ptr<Peer> PeerPtr;
      44             : 
      45             : class Peer {
      46             : public:
      47             :     typedef std::map<std::string, Peer *> PeerMap;
      48             :     typedef std::pair<std::string, Peer *> PeerPair;
      49             :     enum Type {
      50             :         MULTICAST_PEER,
      51             :         EVPN_PEER,
      52             :         BGP_PEER,
      53             :         EVPN_ROUTING_PEER,
      54             :         LINKLOCAL_PEER,
      55             :         ECMP_PEER,
      56             :         VXLAN_BGP_PEER,
      57             :         LOCAL_VM_PORT_PEER,
      58             :         LOCAL_VM_PEER,
      59             :         LOCAL_PEER,
      60             :         NOVA_PEER,
      61             :         VGW_PEER,
      62             :         MULTICAST_FABRIC_TREE_BUILDER,
      63             :         OVS_PEER,
      64             :         MULTICAST_TOR_PEER,
      65             :         MAC_VM_BINDING_PEER,
      66             :         INET_EVPN_PEER,
      67             :         MAC_LEARNING_PEER, /* The peer has the lowest priority
      68             :                           to prevent interference with other paths */
      69             :     };
      70             : 
      71             :     Peer(Type type, const std::string &name, bool controller_export);
      72             :     virtual ~Peer();
      73             : 
      74       18202 :     bool IsLess(const Peer *rhs) const {
      75       18202 :         if  (type_ != rhs->type_) {
      76       15034 :             return type_ < rhs->type_;
      77             :         }
      78             : 
      79        3168 :         return Compare(rhs);
      80             :     }
      81           0 :     virtual bool Compare(const Peer *rhs) const {return false;}
      82             :     // Should we export path from this peer to controller?
      83        3532 :     virtual bool export_to_controller() const {return export_to_controller_;}
      84             :     virtual const Ip4Address *NexthopIp(Agent *agent,
      85             :                                         const AgentPath *path) const;
      86             : 
      87       15257 :     const std::string &GetName() const { return name_; }
      88      114858 :     const Type GetType() const { return type_; }
      89             : 
      90       13474 :     virtual bool SkipAddChangeRequest() const { return false; }
      91             : 
      92       26547 :     virtual bool IsDeleted() const { return false; }
      93             : 
      94          42 :     uint32_t refcount() const { return refcount_; }
      95        3930 :     uint64_t sequence_number() const {return sequence_number_;}
      96          19 :     void incr_sequence_number() {sequence_number_++;}
      97             : 
      98             : private:
      99             :     friend void intrusive_ptr_add_ref(const Peer *p);
     100             :     friend void intrusive_ptr_release(const Peer *p);
     101             : 
     102             :     virtual bool DeleteOnZeroRefcount() const;
     103             : 
     104             :     Type type_;
     105             :     std::string name_;
     106             :     bool export_to_controller_;
     107             :     mutable std::atomic<uint32_t> refcount_;
     108             :     // Sequence number can be used for tracking event based changes like
     109             :     // add/update on peer flaps(as example).
     110             :     uint64_t sequence_number_;
     111             :     DISALLOW_COPY_AND_ASSIGN(Peer);
     112             : };
     113             : 
     114             : // DynamicPeer is one of the base class for Peer to be used for
     115             : // all the Dynamic Peers.
     116             : // This provide Peer pointer sanity using references ensuring
     117             : // that the Peer pointer will be accessible till all the Async
     118             : // DB Requests for this Peer has been processed and all the route
     119             : // Paths are removed
     120             : class DynamicPeer : public Peer {
     121             : public:
     122             :     // Dynamic peer clean up is supposed to be relatively faster process
     123             :     // however trigger a timeoout after 5 mins to catch if any issue
     124             :     // happend
     125             :     static const uint32_t kDeleteTimeout = 300 * 1000;
     126             : 
     127             :     DynamicPeer(Agent *agent, Type type, const std::string &name,
     128             :                 bool controller_export);
     129             :     virtual ~DynamicPeer();
     130             : 
     131             :     // Skip Add/Change request if set
     132        1813 :     virtual bool SkipAddChangeRequest() const { return skip_add_change_; }
     133             : 
     134        3393 :     virtual bool IsDeleted() const { return deleted_; }
     135             : 
     136             :     // only sets skip_add_change to true, should be set only just
     137             :     // before triggering a delete on Peer and a reset is not needed
     138          42 :     void StopRouteExports() { skip_add_change_ = true; }
     139             : 
     140             :     static void ProcessDelete(DynamicPeer *p);
     141             : 
     142             :     bool DeleteTimeout();
     143             : 
     144             : private:
     145             :     friend void intrusive_ptr_add_ref(const Peer *p);
     146             :     friend void intrusive_ptr_release(const Peer *p);
     147             : 
     148             :     virtual bool DeleteOnZeroRefcount() const;
     149             : 
     150             :     Timer *delete_timeout_timer_;
     151             :     std::atomic<bool> deleted_;
     152             :     std::atomic<bool> skip_add_change_;
     153             :     DISALLOW_COPY_AND_ASSIGN(DynamicPeer);
     154             : };
     155             : 
     156             : // Peer used for BGP paths
     157             : class BgpPeer : public DynamicPeer {
     158             : public:
     159             :     typedef boost::function<void()> WalkDoneCb;
     160             :     BgpPeer(AgentXmppChannel *channel,
     161             :             const Ip4Address &server_ip, const std::string &name,
     162             :             DBTableBase::ListenerId id, Peer::Type bgp_peer_type);
     163             :     virtual ~BgpPeer();
     164             : 
     165           0 :     bool Compare(const Peer *rhs) const {
     166           0 :         const BgpPeer *bgp = static_cast<const BgpPeer *>(rhs);
     167           0 :         return server_ip_ < bgp->server_ip_;
     168             :     }
     169             : 
     170             :     // For testing
     171             :     void SetVrfListenerId(DBTableBase::ListenerId id) { id_ = id; }
     172        5158 :     DBTableBase::ListenerId GetVrfExportListenerId() { return id_; }
     173             : 
     174             :     // Table Walkers
     175             :     //Notify walker
     176             :     void PeerNotifyRoutes(WalkDoneCb cb);
     177             :     void PeerNotifyMulticastRoutes(bool associate);
     178             :     void AllocPeerNotifyWalker();
     179             :     void ReleasePeerNotifyWalker();
     180             :     void StopPeerNotifyRoutes();
     181             :     //Del peer walker
     182             :     void DelPeerRoutes(WalkDoneCb walk_done_cb,
     183             :                        uint64_t sequence_number);
     184             :     void DeleteStale();
     185             :     void AllocDeleteStaleWalker();
     186             :     void ReleaseDeleteStaleWalker();
     187             :     void AllocDeletePeerWalker();
     188             :     void ReleaseDeletePeerWalker();
     189             :     void StopDeleteStale();
     190             : 
     191             :     ControllerRouteWalker *route_walker() const;
     192             :     ControllerRouteWalker *delete_stale_walker() const;
     193             :     ControllerRouteWalker *delete_peer_walker() const;
     194             : 
     195             :     //Helper routines to get export state for vrf and route
     196             :     DBState *GetVrfExportState(DBTablePartBase *partition,
     197             :                                DBEntryBase *e);
     198             :     DBState *GetRouteExportState(DBTablePartBase *partition,
     199             :                                  DBEntryBase *e);
     200             :     void DeleteVrfState(DBTablePartBase *partition, DBEntryBase *entry);
     201             : 
     202             :     uint32_t setup_time() const {return setup_time_;}
     203             :     Agent *agent() const;
     204             :     AgentXmppChannel *GetAgentXmppChannel() const;
     205             :     uint64_t ChannelSequenceNumber() const;
     206             :     void set_route_walker_cb(WalkDoneCb cb);
     207             :     void set_delete_stale_walker_cb(WalkDoneCb cb);
     208             :     void set_delete_peer_walker_cb(WalkDoneCb cb);
     209             : 
     210             : private:
     211             :     AgentXmppChannel *channel_;
     212             :     Ip4Address server_ip_;
     213             :     DBTableBase::ListenerId id_;
     214             :     uint32_t setup_time_;
     215             :     AgentRouteWalkerPtr route_walker_;
     216             :     AgentRouteWalkerPtr delete_peer_walker_;
     217             :     AgentRouteWalkerPtr delete_stale_walker_;
     218             :     WalkDoneCb route_walker_cb_;
     219             :     WalkDoneCb delete_stale_walker_cb_;
     220             :     WalkDoneCb delete_peer_walker_cb_;
     221             :     DISALLOW_COPY_AND_ASSIGN(BgpPeer);
     222             : };
     223             : 
     224             : // Peer for local-vm-port paths. There can be multiple VMs with same IP.
     225             : // They are all added as different path. ECMP path will consolidate all
     226             : // local-vm-port paths
     227             : class LocalVmPortPeer : public Peer {
     228             : public:
     229         169 :     LocalVmPortPeer(const std::string &name, uint64_t handle) :
     230         169 :         Peer(Peer::LOCAL_VM_PORT_PEER, name, true), handle_(handle) {
     231         169 :     }
     232             : 
     233         338 :     virtual ~LocalVmPortPeer() { }
     234             : 
     235        3168 :     bool Compare(const Peer *rhs) const {
     236        3168 :         const LocalVmPortPeer *local =
     237             :             static_cast<const LocalVmPortPeer *>(rhs);
     238        3168 :         return handle_ < local->handle_;
     239             :     }
     240             : 
     241             : private:
     242             :     uint64_t handle_;
     243             :     DISALLOW_COPY_AND_ASSIGN(LocalVmPortPeer);
     244             : };
     245             : 
     246             : // ECMP peer
     247             : class EcmpPeer : public Peer {
     248             : public:
     249             :     EcmpPeer() : Peer(Peer::ECMP_PEER, "ECMP", true) { }
     250             :     virtual ~EcmpPeer() { }
     251             : 
     252             :     bool Compare(const Peer *rhs) const { return false; }
     253             : private:
     254             :     DISALLOW_COPY_AND_ASSIGN(EcmpPeer);
     255             : };
     256             : 
     257             : // EVPN peer
     258             : class EvpnPeer : public Peer {
     259             : public:
     260             :     typedef boost::shared_ptr<EvpnPeer> EvpnPeerRef;
     261             : 
     262           2 :     EvpnPeer() : Peer(Peer::EVPN_PEER, "EVPN", false) { }
     263           4 :     virtual ~EvpnPeer() { }
     264             : 
     265           0 :     bool Compare(const Peer *rhs) const { return false; }
     266             : private:
     267             :     DISALLOW_COPY_AND_ASSIGN(EvpnPeer);
     268             : };
     269             : 
     270             : // Inet EVPN peer
     271             : class InetEvpnPeer : public Peer {
     272             : public:
     273             :     typedef boost::shared_ptr<EvpnPeer> InetEvpnPeerRef;
     274             : 
     275           2 :     InetEvpnPeer() : Peer(Peer::INET_EVPN_PEER, "INET-EVPN", false) { }
     276           4 :     virtual ~InetEvpnPeer() { }
     277             : 
     278           0 :     bool Compare(const Peer *rhs) const { return false; }
     279             : private:
     280             :     DISALLOW_COPY_AND_ASSIGN(InetEvpnPeer);
     281             : };
     282             : 
     283             : // EVPN routing peer
     284             : class EvpnRoutingPeer : public Peer {
     285             : public:
     286             :     typedef boost::shared_ptr<EvpnPeer> EvpnRoutingPeerRef;
     287             : 
     288           2 :     EvpnRoutingPeer() : Peer(Peer::EVPN_ROUTING_PEER, "EVPN-ROUTING", false) { }
     289           4 :     virtual ~EvpnRoutingPeer() { }
     290             : 
     291           0 :     bool Compare(const Peer *rhs) const { return false; }
     292             : private:
     293             :     DISALLOW_COPY_AND_ASSIGN(EvpnRoutingPeer);
     294             : };
     295             : 
     296             : // EVPN routing peer
     297             : class VxlanBgpPeer : public Peer {
     298             : public:
     299             :     typedef boost::shared_ptr<VxlanBgpPeer> VxlanBgpPeerRef;
     300             : 
     301           2 :     VxlanBgpPeer() : Peer(Peer::VXLAN_BGP_PEER, "VxLAN BGP PEER", false) { }
     302           4 :     virtual ~VxlanBgpPeer() { }
     303             : 
     304           0 :     bool Compare(const Peer *rhs) const { return false; }
     305             : private:
     306             :     DISALLOW_COPY_AND_ASSIGN(VxlanBgpPeer);
     307             : };
     308             : 
     309             : #endif // vnsw_agent_peer_h_

Generated by: LCOV version 1.14