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