Line data Source code
1 : /* 2 : * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include <init/agent_param.h> 6 : #include "mac_learning_proto.h" 7 : #include "mac_learning_proto_handler.h" 8 : #include "mac_learning.h" 9 : #include "mac_ip_learning.h" 10 : #include "mac_ip_learning_proto_handler.h" 11 : #include "mac_aging.h" 12 : 13 3 : MacLearningProto::MacLearningProto(Agent *agent, boost::asio::io_context &io): 14 : Proto(agent, kTaskMacLearning, PktHandler::MAC_LEARNING, io), 15 3 : add_tokens_("Add Tokens", this, agent->params()->mac_learning_add_tokens()), 16 3 : change_tokens_("Change tokens", this, 17 3 : agent->params()->mac_learning_update_tokens()), 18 3 : delete_tokens_("Delete tokens", this, 19 6 : agent->params()->mac_learning_delete_tokens()) { 20 3 : Init(); 21 3 : } 22 : 23 : ProtoHandler* 24 0 : MacLearningProto::AllocProtoHandler(boost::shared_ptr<PktInfo> info, 25 : boost::asio::io_context &io) { 26 0 : if (info->agent_hdr.cmd == AgentHdr::TRAP_MAC_IP_LEARNING) { 27 0 : return new MacIpLearningProtoHandler(agent(), info, io); 28 : } else { 29 0 : return new MacLearningProtoHandler(agent(), info, io); 30 : } 31 : } 32 : 33 237 : uint32_t MacLearningProto::Hash(uint32_t vrf_id, const MacAddress &mac) { 34 237 : size_t val = 0; 35 : uint8_t mac_array[ETH_ALEN]; 36 : 37 237 : boost::hash_combine(val, vrf_id); 38 237 : mac.ToArray(mac_array, sizeof(mac_array)); 39 : 40 1659 : for (uint32_t i = 0; i < ETH_ALEN; i++) { 41 1422 : boost::hash_combine(val, mac_array[i]); 42 : } 43 : 44 237 : return val % mac_learning_partition_list_.size(); 45 : } 46 : 47 : bool 48 0 : MacLearningProto::Enqueue(PktInfoPtr msg) { 49 : //XXXX disable trace ?? 50 : //FreeBuffer(msg.get()); 51 : MacLearningEntryRequestPtr ptr(new MacLearningEntryRequest( 52 0 : MacLearningEntryRequest::VROUTER_MSG, msg)); 53 : 54 0 : uint32_t table_index = Hash(msg->agent_hdr.vrf, msg->smac); 55 0 : MacLearningPartition* partition = Find(table_index); 56 0 : assert(partition); 57 0 : partition->Enqueue(ptr); 58 0 : return true; 59 0 : } 60 : 61 : 62 0 : TokenPtr MacLearningProto::GetToken(MacLearningEntryRequest::Event event) { 63 0 : switch(event) { 64 0 : case MacLearningEntryRequest::ADD_MAC: 65 0 : return add_tokens_.GetToken(); 66 : 67 0 : case MacLearningEntryRequest::RESYNC_MAC: 68 0 : return change_tokens_.GetToken(); 69 : 70 0 : case MacLearningEntryRequest::DELETE_MAC: 71 0 : return delete_tokens_.GetToken(); 72 : 73 0 : default: 74 0 : assert(0); 75 : } 76 : 77 : return add_tokens_.GetToken(); 78 : } 79 : 80 : MacLearningPartition* 81 336 : MacLearningProto::Find(uint32_t idx) { 82 336 : if (idx >= mac_learning_partition_list_.size()) { 83 0 : assert(0); 84 : return NULL; 85 : } 86 : 87 336 : return mac_learning_partition_list_[idx].get(); 88 : } 89 : 90 0 : void MacLearningProto::TokenAvailable(TokenPool *pool) { 91 0 : pool->IncrementRestarts(); 92 0 : for (uint32_t i = 0; 93 0 : i < agent()->params()->mac_learning_thread_count(); i++) { 94 0 : mac_learning_partition_list_[i]->MayBeStartRunner(pool); 95 : } 96 0 : } 97 : 98 : void 99 3 : MacLearningProto::Init() { 100 6 : for (uint32_t i = 0; 101 6 : i < agent()->params()->mac_learning_thread_count(); i++) { 102 3 : MacLearningPartitionPtr ptr(new MacLearningPartition(agent(), this, i)); 103 3 : mac_learning_partition_list_.push_back(ptr); 104 3 : } 105 3 : mac_ip_learning_tbl_.reset(new MacIpLearningTable(agent(), this)); 106 3 : } 107 101 : MacIpLearningTable* MacLearningProto::GetMacIpLearningTable() { 108 101 : return mac_ip_learning_tbl_.get(); 109 : }