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

Generated by: LCOV version 1.14