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