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

Generated by: LCOV version 1.14