Line data Source code
1 : /////////////////////////////////////////////////////////////////////////////
2 : // vxlan.h
3 : // vnsw/agent
4 : /////////////////////////////////////////////////////////////////////////////
5 :
6 : #ifndef vnsw_agent_vxlan_hpp
7 : #define vnsw_agent_vxlan_hpp
8 :
9 : #include <cmn/agent_cmn.h>
10 : #include <cmn/agent.h>
11 : #include <agent_types.h>
12 : #include <oper/nexthop.h>
13 :
14 : class VxLanId : AgentRefCount<VxLanId>, public AgentDBEntry {
15 : public:
16 24 : VxLanId(uint32_t vxlan_id) : AgentDBEntry(), vxlan_id_(vxlan_id){ }
17 : virtual ~VxLanId();
18 :
19 42 : bool IsLess(const DBEntry &rhs) const {
20 42 : const VxLanId &vxlan_id = static_cast<const VxLanId &>(rhs);
21 42 : return vxlan_id_ < vxlan_id.vxlan_id_;
22 : };
23 0 : virtual string ToString() const { return "vxlan_id"; };
24 : virtual void SetKey(const DBRequestKey *key);
25 : virtual KeyPtr GetDBRequestKey() const;
26 :
27 21 : uint32_t vxlan_id() const {return vxlan_id_;};
28 27 : const NextHop *nexthop() const {return nh_.get();};
29 :
30 3 : uint32_t GetRefCount() const {
31 3 : return AgentRefCount<VxLanId>::GetRefCount();
32 : }
33 :
34 : bool DBEntrySandesh(Sandesh *sresp, std::string &name) const;
35 : void SendObjectLog(const AgentDBTable *table,
36 : AgentLogEvent::type event) const;
37 :
38 : private:
39 : uint32_t vxlan_id_;
40 : NextHopRef nh_;
41 : friend class VxLanTable;
42 : DISALLOW_COPY_AND_ASSIGN(VxLanId);
43 : };
44 :
45 : class VxLanIdKey : public AgentKey {
46 : public:
47 21 : VxLanIdKey(uint32_t vxlan_id) :
48 21 : AgentKey(), vxlan_id_(vxlan_id) { };
49 27 : virtual ~VxLanIdKey() { };
50 24 : uint32_t vxlan_id() const {return vxlan_id_;}
51 :
52 : private:
53 : uint32_t vxlan_id_;
54 : };
55 :
56 : class VxLanIdData : public AgentData {
57 : public:
58 3 : VxLanIdData(const string &vrf_name,
59 : DBRequest &req,
60 : bool mirror_destination,
61 3 : bool bridge) :
62 3 : vrf_name_(vrf_name) {
63 3 : nh_req_.Swap(&req);
64 3 : mirror_destination_ = mirror_destination;
65 3 : bridge_ = bridge;
66 3 : };
67 6 : virtual ~VxLanIdData() { };
68 3 : string &vrf_name() {return vrf_name_;}
69 3 : DBRequest &nh_req() {return nh_req_;}
70 3 : bool mirror_destination() const {return mirror_destination_;}
71 3 : bool bridge() const {return bridge_;}
72 :
73 : private:
74 : string vrf_name_;
75 : DBRequest nh_req_;
76 : bool mirror_destination_;
77 : bool bridge_;
78 : };
79 :
80 : /////////////////////////////////////////////////////////////////////////////
81 : // Implementation of Vxlan(vxlan_id) Table
82 : /////////////////////////////////////////////////////////////////////////////
83 : class VxLanTable : public AgentDBTable {
84 : public:
85 : //////////////////////////////////////////////////////////////////////////
86 : // VxLan entries are created from VN.
87 : // Ideally, each VN should have a different VxLan configured. However,
88 : // there can be transition where more than one VN can have same VxLan.
89 : // A config tree is maintained to handle the transition cases.
90 : //
91 : // The config tree is keyed with <vxlan-id, vn-name> and data is
92 : // <vrf-name, flood_unknown_unicast, active>
93 : //
94 : // For a given vxlan, there can be more than one ConfigEntries. The active
95 : // flag speicified, which config-entry is master for the vxlan.
96 : //
97 : // When first config entry is added for a vxlan, it becomes "active" and
98 : // also creates a vxlan entry.
99 : //
100 : // When subsequent config entry are added, they become "inactive" and are
101 : // added to config-tree. There is no change done to vxlan entry
102 : //
103 : // If an "active" config-entry is deleted, we will pick the first entry
104 : // for given vxlan and make it "active"
105 : //////////////////////////////////////////////////////////////////////////
106 : struct ConfigKey {
107 12 : ConfigKey(uint32_t vxlan_id, const boost::uuids::uuid &vn) :
108 12 : vxlan_id_(vxlan_id), vn_(vn) {
109 12 : }
110 2 : ConfigKey() : vxlan_id_(0), vn_() { }
111 :
112 6 : bool operator()(const ConfigKey &lhs, const ConfigKey &rhs) const {
113 6 : if (lhs.vxlan_id_ != rhs.vxlan_id_)
114 0 : return lhs.vxlan_id_ < rhs.vxlan_id_;
115 :
116 6 : return lhs.vn_ < rhs.vn_;
117 : }
118 :
119 : uint32_t vxlan_id_;
120 : boost::uuids::uuid vn_;
121 : };
122 :
123 : struct ConfigEntry {
124 3 : ConfigEntry(const std::string &vrf, bool flood_unknown_unicast,
125 3 : bool active, bool mirror_destination, bool bridge) :
126 3 : vrf_(vrf), flood_unknown_unicast_(flood_unknown_unicast),
127 3 : active_(active), mirror_destination_(mirror_destination),
128 3 : learning_enabled_(false), bridge_(bridge) {
129 3 : }
130 :
131 : std::string vrf_;
132 : bool flood_unknown_unicast_;
133 : bool active_;
134 : bool mirror_destination_;
135 : bool learning_enabled_;
136 : bool bridge_;
137 : };
138 : typedef std::map<ConfigKey, ConfigEntry, ConfigKey> ConfigTree;
139 : typedef std::map<uint32_t, ComponentNHKeyList>VxlanCompositeNHList;
140 : typedef std::pair<uint32_t , ComponentNHKeyList> VxlanCompositeNHEntry;
141 : static const uint32_t kInvalidvxlan_id = 0;
142 2 : VxLanTable(DB *db, const std::string &name) : AgentDBTable(db, name) { };
143 4 : virtual ~VxLanTable() { };
144 :
145 : virtual std::unique_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
146 24 : virtual size_t Hash(const DBEntry *entry) const {return 0;};
147 21 : virtual size_t Hash(const DBRequestKey *key) const {return 0;};
148 :
149 : virtual DBEntry *Add(const DBRequest *req);
150 : virtual bool OnChange(DBEntry *entry, const DBRequest *req);
151 : virtual bool Delete(DBEntry *entry, const DBRequest *req);
152 : virtual void OnZeroRefcount(AgentDBEntry *e);
153 : virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
154 : const std::string &context);
155 :
156 : void Process(DBRequest &req);
157 :
158 : void Create(uint32_t vxlan_id, const std::string &vrf_name,
159 : bool flood_unknown_unicast, bool mirror_destination,
160 : bool learning_enabled, bool bridge);
161 : void Delete(uint32_t vxlan_id);
162 :
163 : VxLanId *Find(uint32_t vxlan_id);
164 : VxLanId *FindNoLock(uint32_t vxlan_id);
165 : VxLanId *Locate(uint32_t vxlan_id, const boost::uuids::uuid &vn,
166 : const std::string &vrf, bool flood_unknown_unicast,
167 : bool mirror_destination, bool learning_enabled,
168 : bool bridge);
169 : VxLanId *Delete(uint32_t vxlan_id, const boost::uuids::uuid &vn);
170 0 : const ConfigTree &config_tree() const { return config_tree_; }
171 : static DBTableBase *CreateTable(DB *db, const std::string &name);
172 : void Initialize();
173 : void Register();
174 : void Shutdown();
175 : void VmInterfaceNotify(DBTablePartBase *partition, DBEntryBase *e);
176 : bool AddCompositeNH(uint32_t vxlan_id, ComponentNHKeyPtr nh_key);
177 : bool DeleteCompositeNH(uint32_t vxlan_id, ComponentNHKeyPtr nh_key);
178 : private:
179 : bool ChangeHandler(VxLanId *vxlan_id, const DBRequest *req);
180 : ConfigTree config_tree_;
181 : DBTableBase::ListenerId vn_table_listener_id_;
182 : DBTableBase::ListenerId interface_listener_id_;
183 : VxlanCompositeNHList vxlan_composite_nh_map_;
184 : DISALLOW_COPY_AND_ASSIGN(VxLanTable);
185 : };
186 :
187 : #endif // vnsw_agent_vxlan_hpp
|