Line data Source code
1 : /* 2 : * * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : * */ 4 : 5 : #include <boost/uuid/uuid_io.hpp> 6 : #include <cmn/agent_cmn.h> 7 : #include <init/agent_param.h> 8 : 9 : #include <base/logging.h> 10 : #include <oper/operdb_init.h> 11 : #include <oper/route_common.h> 12 : #include <oper/interface_common.h> 13 : #include <oper/vrf.h> 14 : #include <oper/agent_sandesh.h> 15 : #include <oper/hbf.h> 16 : #include <oper/agent_route_walker.h> 17 : 18 : 19 : #include <sandesh/sandesh_types.h> 20 : #include <sandesh/sandesh_constants.h> 21 : #include <sandesh/sandesh.h> 22 : #include <sandesh/sandesh_trace.h> 23 : 24 : #include <string.h> 25 : 26 : using namespace std; 27 : using namespace boost::uuids; 28 : 29 : SandeshTraceBufferPtr HBFTraceBuf(SandeshTraceBufferCreate("HBF", 2000)); 30 : 31 0 : HBFHandler::HBFHandler(Agent* agent) : 32 0 : agent_(agent), 33 0 : interface_listener_id_(DBTable::kInvalidId) { 34 0 : } 35 : 36 0 : void HBFHandler::Register() { 37 0 : interface_listener_id_ = agent_->interface_table()->Register( 38 : boost::bind(&HBFHandler::ModifyVmInterface, this, _1, _2)); 39 0 : HBFTRACE(Trace, "HBFHandler registered for interface table"); 40 0 : } 41 : 42 0 : void HBFHandler::Terminate() { 43 0 : agent_->interface_table()->Unregister(interface_listener_id_); 44 0 : } 45 : 46 0 : bool HBFHandler::IsHBFLInterface(VmInterface *vm_itf) { 47 0 : return (vm_itf->hbs_intf_type() == VmInterface::HBS_INTF_LEFT); 48 : } 49 : 50 0 : bool HBFHandler::IsHBFRInterface(VmInterface *vm_itf) { 51 0 : return (vm_itf->hbs_intf_type() == VmInterface::HBS_INTF_RIGHT); 52 : } 53 : 54 : /* Registered call for VM */ 55 0 : void HBFHandler::ModifyVmInterface(DBTablePartBase *partition, 56 : DBEntryBase *e) 57 : { 58 0 : Interface *intf = static_cast<Interface *>(e); 59 : VmInterface *vm_itf; 60 : 61 0 : if (intf->type() != Interface::VM_INTERFACE) { 62 0 : return; 63 : } 64 : 65 0 : vm_itf = static_cast<VmInterface *>(intf); 66 : HBFIntfDBState *state = static_cast<HBFIntfDBState *>( 67 0 : vm_itf->GetState(partition->parent(), interface_listener_id_)); 68 : 69 : // When this function is invoked for Delete, VMI's vn can be NULL. Use its 70 : // state to figure out if it is HBF VMI 71 0 : if (!IsHBFLInterface(vm_itf) && !IsHBFRInterface(vm_itf) && !state) { 72 0 : return; 73 : } 74 : 75 0 : HBFTRACE(Trace, "vmi notification for " + vm_itf->ToString()); 76 0 : if (intf->IsDeleted() || ((vm_itf->l2_active() == false) && 77 0 : (vm_itf->ipv4_active() == false) && 78 0 : (vm_itf->ipv6_active() == false))) { 79 0 : if (state) { 80 0 : vm_itf->ClearState(partition->parent(), interface_listener_id_); 81 : HBFVrfWalker *walker = static_cast<HBFVrfWalker*> 82 0 : (state->vrf_walker_.get()); 83 0 : if (walker) { 84 0 : HBFTRACE(Trace, "Starting VRF walk for deletion of " 85 : + vm_itf->ToString()); 86 0 : walker->WalkDoneCallback(boost::bind 87 : (&HBFVrfWalker::WalkDone, 88 : static_cast<HBFVrfWalker *>( walker))); 89 0 : walker->Start(Interface::kInvalidIndex, 90 0 : state->lintf_, 91 0 : state->projname_); 92 : } 93 0 : delete state; 94 : } 95 0 : return; 96 : } 97 : 98 0 : if (state == NULL && vm_itf->vn()) { 99 0 : state = new HBFIntfDBState(IsHBFLInterface(vm_itf), vm_itf->vn()->GetProject()); 100 0 : state->vrf_walker_.reset(new HBFVrfWalker("HBFVrfWalker", agent_)); 101 0 : agent_->oper_db()->agent_route_walk_manager()-> 102 0 : RegisterWalker(static_cast<AgentRouteWalker *>(state->vrf_walker_.get())); 103 0 : vm_itf->SetState(partition->parent(), interface_listener_id_, state); 104 : } else { 105 : // Dont have to process Change? TODO 106 0 : return; 107 : } 108 : 109 0 : if (state->vrf_walker_.get()) { 110 0 : HBFTRACE(Trace, "Starting VRF walk for addition of " 111 : + vm_itf->ToString()); 112 0 : HBFVrfWalker *walker = static_cast<HBFVrfWalker*>(state->vrf_walker_.get()); 113 0 : if (walker) { 114 0 : walker->Start(vm_itf->id(), 115 0 : state->lintf_, 116 0 : state->projname_); 117 : } 118 : } 119 : } 120 : 121 0 : HBFVrfWalker::HBFVrfWalker(const std::string &name, Agent *agent) : 122 0 : AgentRouteWalker(name, agent) { 123 0 : } 124 : 125 0 : HBFVrfWalker::~HBFVrfWalker() { 126 0 : } 127 : 128 0 : bool HBFVrfWalker::VrfWalkNotify(DBTablePartBase *partition, 129 : DBEntryBase *e) { 130 0 : VrfEntry *vrf = dynamic_cast<VrfEntry*>(e); 131 : 132 0 : if (vrf && vrf->vn()) { 133 0 : if (projname_ == vrf->vn()->GetProject()) { 134 0 : if (hbf_lintf_) { 135 0 : vrf->set_hbf_lintf(hbf_intf_); 136 0 : std::stringstream ss; 137 0 : ss << "Setting lintf to " << hbf_intf_ 138 0 : << " for vrf " << vrf->vrf_id() << " name " << vrf->GetName(); 139 0 : HBFTRACE(Trace, ss.str()); 140 0 : } else { 141 0 : vrf->set_hbf_rintf(hbf_intf_); 142 0 : std::stringstream ss; 143 0 : ss << "Setting rintf to " << hbf_intf_ 144 0 : << " for vrf " << vrf->vrf_id() << " name " << vrf->GetName(); 145 0 : HBFTRACE(Trace, ss.str()); 146 0 : } 147 : } 148 : 149 0 : vrf->Notify(); 150 : } 151 0 : return true; 152 : } 153 : 154 0 : void HBFVrfWalker::Start(uint32_t hbf_intf, bool hbf_lintf, std::string projname) { 155 0 : hbf_intf_ = hbf_intf; 156 0 : hbf_lintf_ = hbf_lintf; 157 0 : projname_ = projname; 158 0 : StartVrfWalk(); 159 0 : }