Line data Source code
1 : /* 2 : * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : #include "mac_learning_init.h" 6 : #include "mac_learning_proto.h" 7 : #include "mac_learning_proto_handler.h" 8 : 9 0 : MacLearningProtoHandler::MacLearningProtoHandler(Agent *agent, 10 : boost::shared_ptr<PktInfo> info, 11 0 : boost::asio::io_context &io): 12 0 : ProtoHandler(agent, info, io), intf_(NULL), vrf_(NULL), table_(NULL), 13 0 : entry_() { 14 0 : } 15 : 16 0 : void MacLearningProtoHandler::Log(std::string msg) { 17 : 18 0 : std::string vrf = ""; 19 0 : std::string intf = ""; 20 0 : if (vrf_ != NULL) { 21 0 : vrf = vrf_->GetName(); 22 : } 23 : 24 0 : if (intf_ != NULL) { 25 0 : intf = intf_->name(); 26 : } 27 : 28 0 : MAC_LEARNING_TRACE(MacLearningTraceBuf, vrf, pkt_info_->smac.ToString(), intf, msg); 29 0 : } 30 : 31 0 : void MacLearningProtoHandler::IngressPktHandler() { 32 0 : const VmInterface *vm_intf = dynamic_cast<const VmInterface *>(intf_); 33 0 : if (vm_intf == NULL) { 34 0 : Log("Ingress packet on non-VMI interface"); 35 0 : return; 36 : } 37 : 38 0 : entry_.reset(new MacLearningEntryLocal(table_, pkt_info_->agent_hdr.vrf, 39 0 : pkt_info_->smac, 40 0 : pkt_info_->agent_hdr.cmd_param, 41 0 : intf_)); 42 : } 43 : 44 0 : void MacLearningProtoHandler::EgressPktHandler() { 45 : const PhysicalInterface *p_intf = 46 0 : dynamic_cast<const PhysicalInterface *>(intf_); 47 0 : if (p_intf == NULL) { 48 0 : Log("Invalid packet on physical interface"); 49 0 : return; 50 : } 51 : 52 0 : if (pkt_info_->pbb_header == NULL) { 53 0 : Log("Non PBB packet on physical interface"); 54 0 : return; 55 : } 56 : 57 0 : std::string bmac_vrf = Agent::NullString(); 58 0 : if (vrf_->vn() && vrf_->vn()->GetVrf()) { 59 0 : bmac_vrf = vrf_->vn()->GetVrf()->GetName(); 60 : } 61 : 62 0 : entry_.reset(new MacLearningEntryPBB(table_, pkt_info_->agent_hdr.vrf, 63 0 : pkt_info_->smac, 64 0 : pkt_info_->agent_hdr.cmd_param, 65 0 : pkt_info_->b_smac)); 66 0 : } 67 : 68 0 : bool MacLearningProtoHandler::Run() { 69 0 : intf_ = agent()->interface_table()-> 70 0 : FindInterface(pkt_info_->agent_hdr.ifindex); 71 0 : if (intf_ == NULL) { 72 0 : Log("Invalid interface"); 73 0 : return true; 74 : } 75 : 76 0 : vrf_ = agent()->vrf_table()->FindVrfFromId(pkt_info_->agent_hdr.vrf); 77 0 : if (vrf_ == NULL) { 78 0 : Log("Invalid VRF"); 79 0 : return true; 80 : } 81 : 82 0 : uint32_t table_index = agent()->mac_learning_proto()->Hash( 83 0 : pkt_info_->agent_hdr.vrf, pkt_info_->smac); 84 0 : table_ = agent()->mac_learning_proto()->Find(table_index); 85 0 : if (table_ == NULL) { 86 0 : Log("Mac learning table not found"); 87 0 : return true; 88 : } 89 : 90 0 : if (intf_->type() == Interface::PHYSICAL) { 91 0 : EgressPktHandler(); 92 : } else { 93 0 : IngressPktHandler(); 94 : } 95 : 96 0 : if (entry_.get()) { 97 0 : table_->Add(entry_); 98 0 : Log("Mac entry added"); 99 : } 100 : 101 0 : return true; 102 : }