Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include <cmn/agent_cmn.h> 6 : #include <boost/uuid/uuid_io.hpp> 7 : 8 : #include <oper/interface_common.h> 9 : #include <oper/mirror_table.h> 10 : #include <oper/vrf.h> 11 : #include <oper/vrf_assign.h> 12 : #include <oper/nexthop.h> 13 : #include <oper/agent_sandesh.h> 14 : 15 : using namespace std; 16 : using namespace boost::uuids; 17 : 18 : VrfAssignTable *VrfAssignTable::vrf_assign_table_; 19 : 20 : /////////////////////////////////////////////////////////////////////////// 21 : // VRF Assignment table routines 22 : /////////////////////////////////////////////////////////////////////////// 23 0 : std::unique_ptr<DBEntry> VrfAssignTable::AllocEntry(const DBRequestKey *k) const { 24 0 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(AllocWithKey(k))); 25 : } 26 : 27 0 : VrfAssign *VrfAssignTable::AllocWithKey(const DBRequestKey *k) const { 28 0 : const VrfAssign::VrfAssignKey *key = 29 : static_cast<const VrfAssign::VrfAssignKey *>(k); 30 0 : VrfAssign *assign = NULL; 31 : 32 0 : VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, key->intf_uuid_, ""); 33 0 : Interface *intrface = static_cast<Interface *> 34 0 : (agent()->interface_table()->Find(&intf_key, true)); 35 : 36 0 : switch (key->type_) { 37 0 : case VrfAssign::VLAN: { 38 : VlanVrfAssign *vlan_assign = 39 0 : new VlanVrfAssign(intrface, key->vlan_tag_); 40 0 : assign = static_cast<VrfAssign *>(vlan_assign); 41 : } 42 0 : break; 43 : 44 0 : default: 45 0 : assert(0); 46 : break; 47 : } 48 : 49 0 : return assign; 50 0 : } 51 : 52 0 : DBEntry *VrfAssignTable::Add(const DBRequest *req) { 53 : const VrfAssign::VrfAssignKey *key = 54 0 : static_cast<const VrfAssign::VrfAssignKey *>(req->key.get()); 55 0 : VrfAssign *rule = AllocWithKey(key); 56 0 : if (rule->interface_.get() == NULL) { 57 0 : delete rule; 58 0 : return NULL; 59 : } 60 : 61 0 : OnChange(rule, req); 62 0 : return rule; 63 : } 64 : 65 : // Assigned VRF can potentially change 66 0 : bool VrfAssignTable::OnChange(DBEntry *entry, const DBRequest *req) { 67 0 : return (static_cast<VrfAssign *>(entry))->Change(req); 68 : } 69 : 70 2 : DBTableBase *VrfAssignTable::CreateTable(DB *db, const string &name) { 71 2 : vrf_assign_table_ = new VrfAssignTable(db, name); 72 2 : vrf_assign_table_->Init(); 73 2 : return vrf_assign_table_; 74 : } 75 : 76 0 : Interface *VrfAssignTable::FindInterface(const uuid &intf_uuid) { 77 0 : VmInterfaceKey key(AgentKey::ADD_DEL_CHANGE, intf_uuid, ""); 78 0 : return static_cast<Interface *> 79 0 : (Agent::GetInstance()->interface_table()->FindActiveEntry(&key)); 80 0 : } 81 : 82 0 : VrfEntry *VrfAssignTable::FindVrf(const string &name) { 83 0 : return Agent::GetInstance()->vrf_table()->FindVrfFromName(name); 84 : } 85 : 86 0 : void VrfAssignTable::CreateVlanReq(const boost::uuids::uuid &intf_uuid, 87 : const std::string &vrf_name, uint16_t vlan_tag) { 88 0 : DBRequest req; 89 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; 90 : 91 0 : VrfAssign::VrfAssignKey *key = new VrfAssign::VrfAssignKey(); 92 0 : key->VlanInit(intf_uuid, vlan_tag); 93 0 : req.key.reset(key); 94 : 95 0 : VrfAssign::VrfAssignData *data = new VrfAssign::VrfAssignData(vrf_name); 96 0 : req.data.reset(data); 97 : 98 0 : vrf_assign_table_->Enqueue(&req); 99 0 : return; 100 0 : } 101 : 102 0 : void VrfAssignTable::DeleteVlanReq(const boost::uuids::uuid &intf_uuid, 103 : uint16_t vlan_tag) { 104 0 : DBRequest req; 105 0 : req.oper = DBRequest::DB_ENTRY_DELETE; 106 : 107 0 : VrfAssign::VrfAssignKey *key = new VrfAssign::VrfAssignKey(); 108 0 : key->VlanInit(intf_uuid, vlan_tag); 109 0 : req.key.reset(key); 110 : 111 0 : req.data.reset(NULL); 112 0 : vrf_assign_table_->Enqueue(&req); 113 0 : return; 114 0 : } 115 : 116 0 : void VrfAssignTable::CreateVlan(const boost::uuids::uuid &intf_uuid, 117 : const std::string &vrf_name, uint16_t vlan_tag) { 118 0 : DBRequest req; 119 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; 120 : 121 0 : VrfAssign::VrfAssignKey *key = new VrfAssign::VrfAssignKey(); 122 0 : key->VlanInit(intf_uuid, vlan_tag); 123 0 : req.key.reset(key); 124 : 125 0 : VrfAssign::VrfAssignData *data = new VrfAssign::VrfAssignData(vrf_name); 126 0 : req.data.reset(data); 127 : 128 0 : vrf_assign_table_->Process(req); 129 0 : return; 130 0 : } 131 : 132 0 : void VrfAssignTable::DeleteVlan(const boost::uuids::uuid &intf_uuid, 133 : uint16_t vlan_tag) { 134 0 : DBRequest req; 135 0 : req.oper = DBRequest::DB_ENTRY_DELETE; 136 : 137 0 : VrfAssign::VrfAssignKey *key = new VrfAssign::VrfAssignKey(); 138 0 : key->VlanInit(intf_uuid, vlan_tag); 139 0 : req.key.reset(key); 140 : 141 0 : req.data.reset(NULL); 142 0 : vrf_assign_table_->Process(req); 143 0 : return; 144 0 : } 145 : 146 0 : VrfAssign *VrfAssignTable::FindVlanReq(const boost::uuids::uuid &intf_uuid, 147 : uint16_t vlan_tag) { 148 0 : VrfAssign::VrfAssignKey key; 149 0 : key.VlanInit(intf_uuid, vlan_tag); 150 0 : return static_cast<VrfAssign *>(vrf_assign_table_->FindActiveEntry(&key)); 151 0 : } 152 : 153 : /////////////////////////////////////////////////////////////////////////// 154 : // VRF Assignment routines 155 : /////////////////////////////////////////////////////////////////////////// 156 0 : bool VrfAssign::IsLess(const DBEntry &rhs) const { 157 0 : const VrfAssign &vassign = static_cast<const VrfAssign &>(rhs); 158 0 : if (type_ != vassign.type_) { 159 0 : return type_ < vassign.type_; 160 : } 161 : 162 0 : if (interface_.get() != vassign.interface_.get()) { 163 0 : return interface_.get() < vassign.interface_.get(); 164 : } 165 : 166 0 : return VrfAssignIsLess(vassign); 167 : } 168 : 169 0 : bool VrfAssign::Change(const DBRequest *req) { 170 0 : bool ret = false; 171 : VrfAssign::VrfAssignData *data = 172 0 : static_cast<VrfAssign::VrfAssignData *>(req->data.get()); 173 : 174 0 : VrfEntry *vrf = VrfAssignTable::GetInstance()->FindVrf(data->vrf_name_); 175 0 : if (vrf_.get() != vrf) { 176 0 : vrf_ = vrf; 177 0 : ret = true; 178 : } 179 : 180 0 : if (VrfAssignChange(req)) { 181 0 : ret = true; 182 : } 183 : 184 0 : return ret; 185 : } 186 : 187 0 : bool VlanVrfAssign::VrfAssignChange(const DBRequest *req) { 188 0 : bool ret = false; 189 : const VrfAssign::VrfAssignKey *key = 190 0 : static_cast<const VrfAssign::VrfAssignKey *>(req->key.get()); 191 0 : VlanNHKey nh_key(key->intf_uuid_, key->vlan_tag_); 192 0 : Agent *agent = Agent::GetInstance(); 193 0 : const NextHop *nh = static_cast<NextHop *> 194 0 : (agent->nexthop_table()->FindActiveEntry(&nh_key)); 195 0 : assert(nh); 196 0 : if (nh_ != nh) { 197 0 : nh_ = nh; 198 0 : ret = true; 199 : } 200 0 : return ret; 201 0 : } 202 : 203 : /////////////////////////////////////////////////////////////////////////// 204 : // VLAN based VRF Assignment routines 205 : /////////////////////////////////////////////////////////////////////////// 206 0 : bool VlanVrfAssign::VrfAssignIsLess(const VrfAssign &rhs) const { 207 0 : const VlanVrfAssign &rhs_vassign = static_cast<const VlanVrfAssign &>(rhs); 208 0 : return (vlan_tag_ < rhs_vassign.vlan_tag_); 209 : } 210 : 211 0 : DBEntryBase::KeyPtr VlanVrfAssign::GetDBRequestKey() const { 212 0 : VrfAssignKey *key = new VrfAssignKey(); 213 0 : key->VlanInit(interface_->GetUuid(), vlan_tag_); 214 0 : return DBEntryBase::KeyPtr(key); 215 : } 216 : 217 0 : void VlanVrfAssign::SetKey(const DBRequestKey *k) { 218 0 : const VrfAssignKey *key = static_cast<const VrfAssignKey *>(k); 219 0 : type_ = key->type_; 220 0 : interface_ = VrfAssignTable::GetInstance()->FindInterface(key->intf_uuid_); 221 0 : vlan_tag_ = key->vlan_tag_; 222 0 : } 223 : 224 0 : bool VlanVrfAssign::DBEntrySandesh(Sandesh *sresp, std::string &name) const { 225 0 : VrfAssignResp *resp = static_cast<VrfAssignResp *> (sresp); 226 : 227 0 : if (!name.empty() && interface_->name().find(name) != string::npos) { 228 0 : return false; 229 : } 230 : 231 0 : VrfAssignSandeshData data; 232 0 : assert(type_ == VrfAssign::VLAN); 233 : 234 0 : data.set_vlan_tag(vlan_tag_); 235 0 : data.set_itf(interface_->name()); 236 0 : if (vrf_.get()) { 237 0 : data.set_vrf(vrf_->GetName()); 238 : } else { 239 0 : data.set_vrf("--ERROR--"); 240 : } 241 : std::vector<VrfAssignSandeshData> &list = 242 : const_cast<std::vector<VrfAssignSandeshData>&> 243 0 : (resp->get_vrf_assign_list()); 244 0 : list.push_back(data); 245 0 : return true; 246 0 : } 247 : 248 0 : void VrfAssignReq::HandleRequest() const { 249 0 : AgentSandeshPtr sand(new AgentVrfAssignSandesh(context(), get_uuid())); 250 0 : sand->DoSandesh(sand); 251 0 : } 252 : 253 0 : AgentSandeshPtr VrfAssignTable::GetAgentSandesh(const AgentSandeshArguments *args, 254 : const std::string &context) { 255 : return AgentSandeshPtr(new AgentVrfAssignSandesh(context, 256 0 : args->GetString("name"))); 257 : }