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