Line data Source code
1 : /* 2 : * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef SRC_VNSW_AGENT_MAC_LEARNING_MAC_LEARNING_H_ 6 : #define SRC_VNSW_AGENT_MAC_LEARNING_MAC_LEARNING_H_ 7 : 8 : #include <mutex> 9 : 10 : #include "cmn/agent.h" 11 : #include "mac_learning_key.h" 12 : #include "mac_learning_base.h" 13 : #include "mac_learning_event.h" 14 : #include "pkt/flow_token.h" 15 : class MacEntryResp; 16 : /* 17 : * High level mac learning modules 18 : * 19 : * MacLearningProto: 20 : * Processes the packet trapped for MAC learning, based on the hash 21 : * of the VRF and MAC particular MAC Learning parition would be chosen 22 : * for further processing 23 : * 24 : * MacLearningPartition: 25 : * A logical context for processing MAC learning requests in parallel 26 : * This modules learns the MAC entry and 27 : * 1> Enqueues a request for route add 28 : * 2> Enqueues a request to MacLearningMgmt for dependency tracking 29 : * 3> Enqueues a request to MacAgingPartiton for aging 30 : * 31 : * MacLearningMgmt: 32 : * This modules builds a dependency tracking for a MAC entry. 33 : * MAC entry would be dependent on interface, VRF and 34 : * a route(in case of PBB tunnel learnt MAC). So given a DB object 35 : * it would have a list of all the MAC learnt on that object so that 36 : * any change can result in resync of MAC entry. 37 : * 38 : * MacLearningDBClient: 39 : * Listens for change on DB object and enqueues a request to MacLearningMgmt 40 : * for revaluation of MAC entry depenedent on this DB object. 41 : * Current DB tables of intereset inclue: 42 : * 1> Interface (For local learnt mac address) 43 : * 2> Route (For mac learnt over PBB) 44 : * 3> VRF 45 : * 46 : * MacAgingPatition: 47 : * For each MacLearningPartition there will be MacAgingPartition, which 48 : * maintains a per VRF list of MAC entries, upon timer expiry based on 49 : * aging timeout configured on VRF and no. of entries in VRF no. of entries 50 : * would be visited for stats and aged if no activity is seen on the entry. 51 : * 52 : * ++++++++++++++++++++ 53 : * + Mac Aging X + 54 : * ++++++++++++++++++++ 55 : * | 56 : * | 57 : * | 58 : * ++++++++++++++++++++++++ 59 : * -->+ MacLearningPartitionX+--| 60 : * | ++++++++++++++++++++++++ | 61 : * +++++++++++++++ | | N:1 +++++++++++++++++++ 62 : * +Packet Proto +-->| |<--->+ MacLearningMgmt + 63 : * +++++++++++++++ | | +++++++++++++++++++ 64 : * | ++++++++++++++++++++++++ | ^ 65 : * -->+ MacLearningPartitionY+--| | 66 : * ++++++++++++++++++++++++ | 67 : * | ++++++++++++++++ 68 : * |1:1 + MacLearning + 69 : * | + DB Client + 70 : * ++++++++++++++++++++ ++++++++++++++++ 71 : * + Mac Aging Y + 72 : * ++++++++++++++++++++ 73 : */ 74 : 75 : class MacLearningPartition; 76 : class MacAgingTable; 77 : class MacAgingPartition; 78 : 79 : class MacPbbLearningEntry : public MacLearningEntry { 80 : public: 81 : typedef std::vector<TokenPtr> TokenList; 82 : MacPbbLearningEntry(MacLearningPartition *table, uint32_t vrf_id, 83 : const MacAddress &mac, uint32_t index); 84 0 : virtual ~MacPbbLearningEntry() {} 85 : virtual bool Add() = 0; 86 : virtual void Delete(); 87 : virtual void Resync(); 88 : virtual void AddWithToken(); 89 : 90 : MacLearningPartition* mac_learning_table() const { 91 : return mac_learning_table_; 92 : } 93 : 94 0 : uint32_t index() const { 95 0 : return index_; 96 : } 97 : 98 0 : const MacAddress& mac() const { 99 0 : return key_.mac_; 100 : } 101 : 102 0 : uint32_t vrf_id() { 103 0 : return key_.vrf_id_; 104 : } 105 : 106 0 : const MacLearningKey& key() const { 107 0 : return key_; 108 : } 109 : 110 0 : void AddToken(TokenPtr ptr) { 111 0 : std::scoped_lock lock(mutex_); 112 0 : list_.push_back(ptr); 113 0 : } 114 : 115 0 : void ReleaseToken() { 116 0 : std::scoped_lock lock(mutex_); 117 0 : list_.clear(); 118 0 : } 119 : 120 0 : void CopyToken(MacLearningEntry *entry) { 121 : MacPbbLearningEntry *entry1 = 122 0 : dynamic_cast<MacPbbLearningEntry *>(entry); 123 0 : std::scoped_lock lock(mutex_); 124 0 : std::scoped_lock lock2(entry1->mutex_); 125 0 : list_ = entry1->list_; 126 0 : entry1->list_.clear(); 127 0 : } 128 : 129 0 : bool HasTokens() { 130 0 : std::scoped_lock lock(mutex_); 131 0 : return list_.size(); 132 0 : } 133 : void EnqueueToTable(MacLearningEntryRequestPtr req); 134 : 135 : protected: 136 : MacLearningPartition *mac_learning_table_; 137 : MacLearningKey key_; 138 : uint32_t index_; 139 : uint32_t ethernet_tag_; 140 : TokenList list_; 141 : std::mutex mutex_; 142 : private: 143 : DISALLOW_COPY_AND_ASSIGN(MacPbbLearningEntry); 144 : }; 145 : //Structure used to hold MAC entry learned 146 : //on local interface 147 : class MacLearningEntryLocal : public MacPbbLearningEntry { 148 : public: 149 : MacLearningEntryLocal(MacLearningPartition *table, uint32_t vrf_id, 150 : const MacAddress &mac, uint32_t index, 151 : InterfaceConstRef intf); 152 0 : virtual ~MacLearningEntryLocal() {} 153 : 154 : bool Add(); 155 : 156 0 : const Interface* intf() { 157 0 : return intf_.get(); 158 : } 159 : 160 : private: 161 : InterfaceConstRef intf_; 162 : DISALLOW_COPY_AND_ASSIGN(MacLearningEntryLocal); 163 : }; 164 : 165 : //Structure used to hold MAC entry learned on 166 : //tunnel packet i.e vxlan scenario for now 167 : class MacLearningEntryRemote : public MacPbbLearningEntry { 168 : public: 169 : MacLearningEntryRemote(MacLearningPartition *table, uint32_t vrf_id, 170 : const MacAddress &mac, uint32_t index, 171 : const IpAddress remote_ip); 172 0 : virtual ~MacLearningEntryRemote() {} 173 : 174 : bool Add(); 175 : 176 : const IpAddress& remote_ip() const { 177 : return remote_ip_; 178 : } 179 : private: 180 : IpAddress remote_ip_; 181 : DISALLOW_COPY_AND_ASSIGN(MacLearningEntryRemote); 182 : }; 183 : 184 : //Structure used to hold MAC entry learned on 185 : //PBB tunnel packet 186 : class MacLearningEntryPBB : public MacPbbLearningEntry { 187 : public: 188 : MacLearningEntryPBB(MacLearningPartition *table, uint32_t vrf_id, 189 : const MacAddress &mac, uint32_t index, 190 : const MacAddress &bmac); 191 0 : virtual ~MacLearningEntryPBB() {} 192 : 193 : bool Add(); 194 : 195 0 : const MacAddress& bmac() const { 196 0 : return bmac_; 197 : } 198 : 199 : private: 200 : const MacAddress bmac_; 201 : DISALLOW_COPY_AND_ASSIGN(MacLearningEntryPBB); 202 : }; 203 : 204 : //Mac learning Parition holds all the mac entries hashed 205 : //based on VRF + MAC, and corresponding to each partition 206 : //there will be a aging partition holding all the MAC entries 207 : //present in this partiton 208 : class MacLearningPartition { 209 : public: 210 : typedef std::pair<MacLearningKey, 211 : MacLearningEntryPtr> MacLearningEntryPair; 212 : typedef std::map<MacLearningKey, 213 : MacLearningEntryPtr, 214 : MacLearningKeyCmp> MacLearningEntryTable; 215 : 216 : MacLearningPartition(Agent *agent, MacLearningProto *proto, 217 : uint32_t id); 218 : virtual ~MacLearningPartition(); 219 : void Add(MacLearningEntryPtr ptr); 220 : void Resync(MacLearningEntryPtr ptr); 221 : void Delete(MacLearningEntryPtr ptr); 222 : void DeleteAll(); 223 : void ReleaseToken(const MacLearningKey &key); 224 : MacLearningEntry* Find(const MacLearningKey &key); 225 : //To be used in test cases only 226 : MacLearningEntryPtr TestGet(const MacLearningKey &key); 227 : bool RequestHandler(MacLearningEntryRequestPtr ptr); 228 : 229 96 : Agent* agent() { 230 96 : return agent_; 231 : } 232 : 233 24 : MacAgingPartition* aging_partition() const { 234 24 : return aging_partition_.get(); 235 : } 236 : 237 9 : uint32_t id() const { 238 9 : return id_; 239 : } 240 : 241 : void Enqueue(MacLearningEntryRequestPtr req); 242 : void EnqueueMgmtReq(MacLearningEntryPtr ptr, bool add); 243 : void MayBeStartRunner(TokenPool *pool); 244 : 245 2 : void SetDeleteQueueDisable(bool disable) { 246 2 : delete_request_queue_.SetQueueDisable(disable); 247 2 : } 248 : 249 : private: 250 : friend class MacLearningSandeshResp; 251 : Agent *agent_; 252 : uint32_t id_; 253 : MacLearningEntryTable mac_learning_table_; 254 : MacLearningRequestQueue add_request_queue_; 255 : MacLearningRequestQueue change_request_queue_; 256 : MacLearningRequestQueue delete_request_queue_; 257 : boost::shared_ptr<MacAgingPartition> aging_partition_; 258 : DISALLOW_COPY_AND_ASSIGN(MacLearningPartition); 259 : }; 260 : 261 : class MacLearningSandeshResp : public Task { 262 : public: 263 : const static uint32_t kMaxResponse = 100; 264 : const static char kDelimiter = '-'; 265 : MacLearningSandeshResp(Agent *agent, MacEntryResp *resp, 266 : std::string resp_ctx, 267 : std::string key, 268 : const MacAddress &mac); 269 : virtual ~MacLearningSandeshResp(); 270 0 : std::string Description() const { return "MacLearningSandeshRespTask"; } 271 : 272 : private: 273 : bool Run(); 274 : bool SetMacKey(string key); 275 : void SendResponse(SandeshResponse *resp); 276 : 277 : const MacLearningPartition* GetPartition(); 278 : std::string GetMacKey(); 279 : 280 : Agent *agent_; 281 : MacEntryResp *resp_; 282 : std::string resp_data_; 283 : uint32_t partition_id_; 284 : uint32_t vrf_id_; 285 : MacAddress mac_; 286 : bool exact_match_; 287 : MacAddress user_given_mac_; 288 : DISALLOW_COPY_AND_ASSIGN(MacLearningSandeshResp); 289 : }; 290 : #endif