LCOV - code coverage report
Current view: top level - vnsw/agent/port_ipc - port_subscribe_table.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 34 45 75.6 %
Date: 2026-11-09 02:10:49 Functions: 23 34 67.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef _VNSW_AGENT_PORT_IPC_PORT_SUBSCRIBE_TABLE_H_
       7             : #define _VNSW_AGENT_PORT_IPC_PORT_SUBSCRIBE_TABLE_H_
       8             : 
       9             : #include <map>
      10             : #include <memory>
      11             : #include <mutex>
      12             : #include <vector>
      13             : #include <string>
      14             : #include <string>
      15             : #include <boost/uuid/uuid.hpp>
      16             : #include <boost/shared_ptr.hpp>
      17             : 
      18             : #include <base/util.h>
      19             : #include <base/address.h>
      20             : #include <db/db_table.h>
      21             : #include <db/db_entry.h>
      22             : #include <vnc_cfg_types.h>
      23             : 
      24             : class InterfaceTable;
      25             : class Agent;
      26             : struct VmInterfaceConfigData;
      27             : class VmiSubscribeEntry;
      28             : class VmVnPortSubscribeEntry;
      29             : class PortSubscribeEntry;
      30             : class PortSubscribeTable;
      31             : typedef boost::shared_ptr<PortSubscribeEntry> PortSubscribeEntryPtr;
      32             : 
      33             : /****************************************************************************
      34             :  * The class is responsible to manage port subscribe/unsubscribe from IPC
      35             :  * channels.
      36             :  ****************************************************************************/
      37             : class PortSubscribeEntry {
      38             : public:
      39             :     enum Type {
      40             :         VMPORT,
      41             :         NAMESPACE,
      42             :         REMOTE_PORT
      43             :     };
      44             : 
      45             :     PortSubscribeEntry(Type type, const std::string &ifname, int32_t version);
      46             :     virtual ~PortSubscribeEntry();
      47             : 
      48             :     virtual void OnAdd(Agent *agent, PortSubscribeTable *table) const = 0;
      49             :     virtual void OnDelete(Agent *agent, PortSubscribeTable *table) const = 0;
      50             :     virtual void Update(const PortSubscribeEntry *rhs);
      51             : 
      52             :     static const char *TypeToString(Type type);
      53        1649 :     Type type() const { return type_; }
      54         330 :     const std::string &ifname() const { return ifname_; }
      55         330 :     uint32_t version() const { return version_; }
      56             : 
      57             :     virtual bool MatchVn(const boost::uuids::uuid &u) const = 0;
      58             :     virtual const boost::uuids::uuid &vn_uuid() const = 0;
      59             :     virtual bool MatchVm(const boost::uuids::uuid &u) const = 0;
      60             :     virtual const boost::uuids::uuid &vm_uuid() const = 0;
      61             : 
      62             : protected:
      63             :     Type type_;
      64             :     std::string ifname_;
      65             :     uint16_t version_;
      66             :     DISALLOW_COPY_AND_ASSIGN(PortSubscribeEntry);
      67             : };
      68             : 
      69             : class VmiSubscribeEntry : public PortSubscribeEntry {
      70             : public:
      71             :     VmiSubscribeEntry(PortSubscribeEntry::Type type, const std::string &ifname,
      72             :                       uint32_t version, const boost::uuids::uuid &vmi_uuid,
      73             :                       const boost::uuids::uuid vm_uuid,
      74             :                       const std::string &vm_name,
      75             :                       const boost::uuids::uuid &vn_uuid,
      76             :                       const boost::uuids::uuid &project_uuid,
      77             :                       const Ip4Address &ip4_addr, const Ip6Address &ip6_addr,
      78             :                       const std::string &mac_addr, uint16_t tx_vlan_id,
      79             :                       uint16_t rx_vlan_id,
      80             :                       uint8_t vhostuser_mode, uint8_t link_state);
      81             :     ~VmiSubscribeEntry();
      82             : 
      83             :     virtual bool MatchVn(const boost::uuids::uuid &u) const;
      84             :     virtual bool MatchVm(const boost::uuids::uuid &u) const;
      85             : 
      86             :     virtual void Update(const PortSubscribeEntry *rhs);
      87             :     void OnAdd(Agent *agent, PortSubscribeTable *table) const;
      88             :     void OnDelete(Agent *agent, PortSubscribeTable *table) const;
      89             : 
      90         495 :     const boost::uuids::uuid &vmi_uuid() const { return vmi_uuid_; }
      91         486 :     const boost::uuids::uuid &vm_uuid() const { return vm_uuid_; }
      92         330 :     const std::string &vm_name() const { return vm_name_; }
      93         505 :     const boost::uuids::uuid &vn_uuid() const { return vn_uuid_; }
      94         330 :     const boost::uuids::uuid &project_uuid() const { return project_uuid_; }
      95         330 :     const Ip4Address &ip4_addr() const { return ip4_addr_; }
      96         330 :     const Ip6Address &ip6_addr() const { return ip6_addr_; }
      97         330 :     const std::string &mac_addr() const { return mac_addr_; }
      98         330 :     uint16_t tx_vlan_id() const { return tx_vlan_id_; }
      99         330 :     uint16_t rx_vlan_id() const { return rx_vlan_id_; }
     100         330 :     uint8_t vhostuser_mode() const { return vhostuser_mode_; }
     101         165 :     uint8_t link_state() const { return link_state_; }
     102           0 :     void set_link_state(uint8_t value) { link_state_ = value; }
     103             : private:
     104             :     boost::uuids::uuid vmi_uuid_;
     105             :     boost::uuids::uuid vm_uuid_;
     106             :     std::string vm_name_;
     107             :     boost::uuids::uuid vn_uuid_;
     108             :     boost::uuids::uuid project_uuid_;
     109             :     Ip4Address ip4_addr_;
     110             :     Ip6Address ip6_addr_;
     111             :     std::string mac_addr_;
     112             :     uint16_t tx_vlan_id_;
     113             :     uint16_t rx_vlan_id_;
     114             :     uint8_t vhostuser_mode_;
     115             :     uint8_t link_state_;
     116             :     DISALLOW_COPY_AND_ASSIGN(VmiSubscribeEntry);
     117             : };
     118             : 
     119             : /****************************************************************************
     120             :  * In case of container orchestrators like k8s/mesos, we do not get VMI UUID
     121             :  * in port-subscribe message. Instead, the interface is addressed by
     122             :  * vm-uuid and vn. The VmVnPortSubscribeEntry class is used for these
     123             :  * scenarios
     124             :  ****************************************************************************/
     125             : class VmVnPortSubscribeEntry : public PortSubscribeEntry {
     126             : public:
     127             :     VmVnPortSubscribeEntry(PortSubscribeEntry::Type type,
     128             :                            const std::string &ifname, uint32_t version,
     129             :                            const boost::uuids::uuid &vm_uuid,
     130             :                            const boost::uuids::uuid &vn_uuid,
     131             :                            const boost::uuids::uuid &vmi_uuid,
     132             :                            const std::string &vm_name,
     133             :                            const std::string &vm_identifier,
     134             :                            const std::string &vm_ifname,
     135             :                            const std::string &vm_namespace);
     136             :     ~VmVnPortSubscribeEntry();
     137             : 
     138             :     virtual bool MatchVn(const boost::uuids::uuid &u) const;
     139           0 :     virtual const boost::uuids::uuid &vn_uuid() const { return vn_uuid_; }
     140             :     virtual bool MatchVm(const boost::uuids::uuid &u) const;
     141           0 :     virtual const boost::uuids::uuid &vm_uuid() const { return vm_uuid_; }
     142             : 
     143             :     virtual void Update(const PortSubscribeEntry *rhs);
     144             :     void OnAdd(Agent *agent, PortSubscribeTable *table) const;
     145             :     void OnDelete(Agent *agent, PortSubscribeTable *table) const;
     146             : 
     147           0 :     const std::string &vm_name() const { return vm_name_; }
     148           0 :     const std::string &vm_identifier() const { return vm_identifier_; }
     149           0 :     const std::string &vm_ifname() const { return vm_ifname_; }
     150           0 :     const std::string &vm_namespace() const { return vm_namespace_; }
     151           0 :     void set_vmi_uuid(const boost::uuids::uuid &u) { vmi_uuid_ = u; }
     152           0 :     const boost::uuids::uuid &vmi_uuid() const { return vmi_uuid_; }
     153             : private:
     154             :     boost::uuids::uuid vm_uuid_;
     155             :     boost::uuids::uuid vn_uuid_;
     156             :     std::string vm_name_;
     157             :     std::string vm_identifier_;
     158             :     std::string vm_ifname_;
     159             :     std::string vm_namespace_;
     160             :     boost::uuids::uuid vmi_uuid_;
     161             :     DISALLOW_COPY_AND_ASSIGN(VmVnPortSubscribeEntry);
     162             : };
     163             : 
     164             : class PortSubscribeTable {
     165             : public:
     166             :     PortSubscribeTable(Agent *agent);
     167             :     virtual ~PortSubscribeTable();
     168             : 
     169             :     struct State : DBState {
     170         167 :         State() : uuid_() { }
     171         334 :         ~State() { }
     172             : 
     173             :         boost::uuids::uuid uuid_;
     174             :     };
     175             : 
     176             :     struct Cmp {
     177        6220 :         bool operator()(const boost::uuids::uuid &lhs,
     178             :                         const boost::uuids::uuid &rhs) const {
     179        6220 :             return lhs < rhs;
     180             :         }
     181             :     };
     182             :     typedef std::map<boost::uuids::uuid, PortSubscribeEntryPtr, Cmp> VmiTree;
     183             :     typedef std::map<boost::uuids::uuid, IFMapNode *> UuidToIFNodeTree;
     184             : 
     185             :     // trees used for managing vm-vn port subscriptions
     186             :     // VmiToVmVnTree       : The tree from vmi-uuid to corresponding
     187             :     //                       vm+vn uuid
     188             :     // VmVnToVmiTree       : Reverse mapping for VmiToVmVnTree. Will be used
     189             :     //                       to find VMI when port-subscription message
     190             :     // Both the tree are built from VmInterfaceConfigData
     191             : 
     192             :     struct VmVnUuidEntry {
     193             :         boost::uuids::uuid vm_uuid_;
     194             :         boost::uuids::uuid vn_uuid_;
     195             :         boost::uuids::uuid vmi_uuid_;
     196             : 
     197        1616 :         VmVnUuidEntry(const boost::uuids::uuid &vm_uuid,
     198             :                       const boost::uuids::uuid &vn_uuid,
     199        1616 :                       const boost::uuids::uuid &vmi_uuid) :
     200        1616 :             vm_uuid_(vm_uuid), vn_uuid_(vn_uuid), vmi_uuid_(vmi_uuid) {
     201        1616 :         }
     202             :         VmVnUuidEntry() :
     203             :             vm_uuid_(boost::uuids::nil_uuid()),
     204             :             vn_uuid_(boost::uuids::nil_uuid()),
     205             :             vmi_uuid_(boost::uuids::nil_uuid()) {
     206             :         }
     207        1996 :         virtual ~VmVnUuidEntry() { }
     208             :     };
     209             : 
     210             :     struct VmVnUuidEntryCmp {
     211        1979 :         bool operator()(const VmVnUuidEntry &lhs,
     212             :                         const VmVnUuidEntry &rhs) const {
     213        1979 :             if (lhs.vm_uuid_ != rhs.vm_uuid_) {
     214        1624 :                 return lhs.vm_uuid_ < rhs.vm_uuid_;
     215             :             }
     216         355 :             if (lhs.vn_uuid_ != rhs.vn_uuid_) {
     217           0 :                 return lhs.vn_uuid_ < rhs.vn_uuid_;
     218             :             }
     219         355 :             return lhs.vmi_uuid_ < rhs.vmi_uuid_;
     220             :         }
     221             :     };
     222             : 
     223             :     struct VmiEntry {
     224             :         boost::uuids::uuid vm_uuid_;
     225             :         boost::uuids::uuid vn_uuid_;
     226             :         bool sub_interface_;
     227             :         boost::uuids::uuid parent_vmi_;
     228             :         uint16_t vlan_tag_;
     229             :         std::string mac_;
     230             :         uint8_t vhostuser_mode_;
     231             :         autogen::VirtualMachineInterface *vmi_cfg;
     232             : 
     233          47 :         VmiEntry() :
     234          47 :             vm_uuid_(), vn_uuid_(), sub_interface_(), parent_vmi_(),
     235          47 :             vlan_tag_(), mac_(), vhostuser_mode_() {
     236          47 :                 vmi_cfg = NULL;
     237          47 :         }
     238             :     };
     239             : 
     240             :     typedef std::map<boost::uuids::uuid, VmiEntry> VmiToVmVnTree;
     241             :     typedef std::map<VmVnUuidEntry, boost::uuids::uuid, VmVnUuidEntryCmp>
     242             :         VmVnToVmiTree;
     243             :     typedef std::map<VmVnUuidEntry, PortSubscribeEntryPtr, VmVnUuidEntryCmp>
     244             :         VmVnTree;
     245             : 
     246             :     void InitDone();
     247             :     void Shutdown();
     248             :     IFMapNode *UuidToIFNode(const boost::uuids::uuid &u) const;
     249             :     void Notify(DBTablePartBase *partition, DBEntryBase *e);
     250             :     void StaleWalk(uint64_t version);
     251           0 :     uint32_t Size() const { return vmi_tree_.size(); }
     252             : 
     253             :     void AddVmi(const boost::uuids::uuid &u, PortSubscribeEntryPtr entry);
     254             :     void DeleteVmi(const boost::uuids::uuid &u);
     255             :     PortSubscribeEntryPtr GetVmi(const boost::uuids::uuid &u) const;
     256             : 
     257             :     void AddVmVnPort(const boost::uuids::uuid &vm_uuid,
     258             :                      const boost::uuids::uuid &vn_uuid,
     259             :                      const boost::uuids::uuid &vmi_uuid,
     260             :                      PortSubscribeEntryPtr entry);
     261             :     void DeleteVmVnPort(const boost::uuids::uuid &vm_uuid,
     262             :                         const boost::uuids::uuid &vn_uuid,
     263             :                         const boost::uuids::uuid &vmi_uuid);
     264             :     PortSubscribeEntryPtr GetVmVnPortNoLock(const boost::uuids::uuid &vm_uuid,
     265             :                                             const boost::uuids::uuid &vn_uuid,
     266             :                                             const boost::uuids::uuid &vmi_uuid);
     267             :     PortSubscribeEntryPtr GetVmVnPort(const boost::uuids::uuid &vm_uuid,
     268             :                                       const boost::uuids::uuid &vn_uuid,
     269             :                                       const boost::uuids::uuid &vmi_uuid);
     270             : 
     271             :     void HandleVmiIfnodeAdd(const boost::uuids::uuid &vmi_uuid,
     272             :                             const VmInterfaceConfigData *data);
     273             :     void HandleVmiIfnodeDelete(const boost::uuids::uuid &vmi_uuid);
     274             : 
     275             :     PortSubscribeEntryPtr Get(const boost::uuids::uuid &vmi_uuid,
     276             :                               const boost::uuids::uuid &vm_uuid,
     277             :                               const boost::uuids::uuid &vn_uuid) const;
     278             : 
     279             :     bool VmVnToVmiSetNoLock(const boost::uuids::uuid &vm_uuid,
     280             :                              std::set<boost::uuids::uuid> &vmi_uuid_set) const;
     281             :     bool VmVnToVmiSet(const boost::uuids::uuid &vm_uuid,
     282             :                        std::set<boost::uuids::uuid> &vmi_uuid_set) const;
     283             :     const VmiEntry *VmiToEntry(const boost::uuids::uuid &vmi_uuid) const;
     284             : 
     285             : private:
     286             :     void UpdateVmiIfnodeInfo(const boost::uuids::uuid &vmi_uuid,
     287             :                              const VmInterfaceConfigData *data);
     288             :     void DeleteVmiIfnodeInfo(const boost::uuids::uuid &vmi_uuid);
     289             : private:
     290             :     friend class SandeshVmiPortSubscribeTask;
     291             :     friend class SandeshVmVnPortSubscribeTask;
     292             :     friend class SandeshVmiToVmVnTask;
     293             :     friend class SandeshVmVnToVmiTask;
     294             : 
     295             :     Agent *agent_;
     296             :     InterfaceTable *interface_table_;
     297             :     VNController *controller_;
     298             :     mutable std::mutex mutex_;
     299             :     VmiTree vmi_tree_;
     300             :     IFMapAgentTable *vmi_config_table_;
     301             :     DBTableBase::ListenerId vmi_config_listener_id_;
     302             :     UuidToIFNodeTree uuid_ifnode_tree_;
     303             :     VmiToVmVnTree vmi_to_vmvn_tree_;
     304             :     VmVnToVmiTree vmvn_to_vmi_tree_;
     305             :     VmVnTree vmvn_subscribe_tree_;
     306             :     DISALLOW_COPY_AND_ASSIGN(PortSubscribeTable);
     307             : };
     308             : 
     309             : #endif //  _VNSW_AGENT_PORT_IPC_PORT_SUBSCRIBE_TABLE_H_

Generated by: LCOV version 1.14