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/asio.hpp> 7 : #include <boost/bind/bind.hpp> 8 : 9 : #include <base/logging.h> 10 : #include <db/db_entry.h> 11 : #include <db/db_table.h> 12 : #include <db/db_table_partition.h> 13 : #include <ksync/ksync_index.h> 14 : #include <ksync/ksync_entry.h> 15 : #include <ksync/ksync_object.h> 16 : #include <ksync/ksync_netlink.h> 17 : #include <ksync/ksync_sock.h> 18 : #include "oper/interface_common.h" 19 : #include "oper/vrf.h" 20 : #include "oper/vrf_assign.h" 21 : #include "oper/mirror_table.h" 22 : #include "vrouter/ksync/interface_ksync.h" 23 : #include "vrouter/ksync/nexthop_ksync.h" 24 : #include "vrouter/ksync/vrf_assign_ksync.h" 25 : #include "ksync_init.h" 26 : 27 : using namespace boost::placeholders; 28 : 29 0 : VrfAssignKSyncEntry::VrfAssignKSyncEntry(VrfAssignKSyncObject* obj, 30 : const VrfAssignKSyncEntry *entry, 31 0 : uint32_t index) : 32 0 : KSyncNetlinkDBEntry(index), ksync_obj_(obj), interface_(entry->interface_), 33 0 : vlan_tag_(entry->vlan_tag_), vrf_id_(entry->vrf_id_), 34 0 : nh_(entry->nh_) { 35 0 : } 36 : 37 0 : VrfAssignKSyncEntry::VrfAssignKSyncEntry(VrfAssignKSyncObject* obj, 38 0 : const VrfAssign *vassign) : 39 0 : KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj) { 40 : 41 : InterfaceKSyncObject *intf_object = 42 0 : ksync_obj_->ksync()->interface_ksync_obj(); 43 0 : InterfaceKSyncEntry intf(intf_object, vassign->GetInterface()); 44 : 45 : interface_ = static_cast<InterfaceKSyncEntry *> 46 0 : (intf_object->GetReference(&intf)); 47 0 : assert(interface_); 48 : 49 0 : assert(vassign->GetType() == VrfAssign::VLAN); 50 0 : const VlanVrfAssign *vlan = static_cast<const VlanVrfAssign *>(vassign); 51 0 : vlan_tag_ = vlan->GetVlanTag(); 52 : 53 0 : if (vassign->GetVrf()) { 54 0 : vrf_id_ = vassign->GetVrf()->vrf_id(); 55 : } else { 56 0 : vrf_id_ = VIF_VRF_INVALID; 57 : } 58 0 : } 59 : 60 0 : VrfAssignKSyncEntry::~VrfAssignKSyncEntry() { 61 0 : } 62 : 63 0 : KSyncDBObject *VrfAssignKSyncEntry::GetObject() const { 64 0 : return ksync_obj_; 65 : } 66 : 67 0 : bool VrfAssignKSyncEntry::IsLess(const KSyncEntry &rhs) const { 68 0 : const VrfAssignKSyncEntry &entry = 69 : static_cast<const VrfAssignKSyncEntry &>(rhs); 70 : 71 0 : if (interface() != entry.interface()) { 72 0 : return interface() < entry.interface(); 73 : } 74 : 75 0 : return vlan_tag() < entry.vlan_tag(); 76 : } 77 : 78 0 : std::string VrfAssignKSyncEntry::ToString() const { 79 0 : std::stringstream s; 80 0 : InterfaceKSyncEntry *intf = interface(); 81 : 82 0 : s << "VRF Assign : "; 83 0 : if (intf) { 84 0 : s << "Interface : " << intf->interface_name() << 85 : " Intf-Service-Vlan : " << 86 0 : (intf->has_service_vlan() == true ? "Enable" : "Disable"); 87 : } else { 88 0 : s << "Interface : <NULL> "; 89 : } 90 : 91 0 : s << " Tag : " << vlan_tag(); 92 : const VrfEntry* vrf = 93 0 : ksync_obj_->ksync()->agent()->vrf_table()->FindVrfFromId(vrf_id_); 94 0 : if (vrf) { 95 0 : s << " Vrf : " << vrf->GetName(); 96 : } 97 : 98 0 : return s.str(); 99 0 : } 100 : 101 0 : bool VrfAssignKSyncEntry::Sync(DBEntry *e) { 102 0 : bool ret = false; 103 0 : const VrfAssign *vassign = static_cast<VrfAssign *>(e); 104 0 : uint32_t vrf_id = 0; 105 : 106 0 : if (vassign->GetVrf()) { 107 0 : vrf_id = vassign->GetVrf()->vrf_id(); 108 : } else { 109 0 : vrf_id = VIF_VRF_INVALID; 110 : } 111 : 112 0 : if (vrf_id_ != vrf_id) { 113 0 : vrf_id_ = vrf_id; 114 0 : ret = true; 115 : } 116 : 117 0 : const VlanVrfAssign *vlan = static_cast<const VlanVrfAssign *>(vassign); 118 0 : vlan_tag_ = vlan->GetVlanTag(); 119 : NHKSyncObject *nh_object = 120 0 : ksync_obj_->ksync()->nh_ksync_obj(); 121 0 : NHKSyncEntry nh(nh_object, vlan->nh()); 122 0 : if (nh_ != static_cast<NHKSyncEntry*>(nh_object->GetReference(&nh))) { 123 0 : nh_ = static_cast<NHKSyncEntry*>(nh_object->GetReference(&nh)); 124 0 : ret = true; 125 : } 126 : 127 0 : return ret; 128 0 : } 129 : 130 0 : InterfaceKSyncEntry *VrfAssignKSyncEntry::interface() const { 131 0 : return static_cast<InterfaceKSyncEntry *>(interface_.get()); 132 : } 133 : 134 0 : NHKSyncEntry *VrfAssignKSyncEntry::nh() const { 135 0 : return static_cast<NHKSyncEntry *>(nh_.get()); 136 : } 137 : 138 0 : int VrfAssignKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) { 139 0 : vr_vrf_assign_req encoder; 140 : int encode_len; 141 0 : InterfaceKSyncEntry *intf = interface(); 142 : 143 0 : encoder.set_h_op(op); 144 0 : encoder.set_var_vif_index(intf->interface_id()); 145 0 : encoder.set_var_vlan_id(vlan_tag_); 146 0 : encoder.set_var_vif_vrf(vrf_id_); 147 0 : encoder.set_var_nh_id(nh()->nh_id()); 148 0 : int error = 0; 149 0 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error); 150 0 : assert(error == 0); 151 0 : assert(encode_len <= buf_len); 152 0 : LOG(DEBUG, "VRF Assign for Interface <" << intf->interface_name() << 153 : "> Tag <" << vlan_tag() << "> Vrf <" << vrf_id_ << ">"); 154 0 : return encode_len; 155 0 : } 156 : 157 0 : int VrfAssignKSyncEntry::AddMsg(char *buf, int buf_len) { 158 0 : LOG(DEBUG, "VrfAssign: Add"); 159 0 : return Encode(sandesh_op::ADD, buf, buf_len); 160 : } 161 : 162 0 : int VrfAssignKSyncEntry::ChangeMsg(char *buf, int buf_len){ 163 0 : return AddMsg(buf, buf_len); 164 : } 165 : 166 0 : int VrfAssignKSyncEntry::DeleteMsg(char *buf, int buf_len) { 167 0 : LOG(DEBUG, "VrfAssign: Delete"); 168 0 : return Encode(sandesh_op::DEL, buf, buf_len); 169 : } 170 : 171 0 : KSyncEntry *VrfAssignKSyncEntry::UnresolvedReference() { 172 0 : InterfaceKSyncEntry *intf = interface(); 173 0 : if (!intf->IsResolvedAndInSync()) { 174 0 : return intf; 175 : } 176 0 : NHKSyncEntry *ksync_nh = nh(); 177 0 : if (!ksync_nh->IsResolvedAndInSync()) { 178 0 : return ksync_nh; 179 : } 180 0 : return NULL; 181 : } 182 : 183 2 : VrfAssignKSyncObject::VrfAssignKSyncObject(KSync *ksync) 184 2 : : KSyncDBObject("KSync VrfAssign"), ksync_(ksync) { 185 2 : } 186 : 187 4 : VrfAssignKSyncObject::~VrfAssignKSyncObject() { 188 4 : } 189 : 190 2 : void VrfAssignKSyncObject::RegisterDBClients() { 191 2 : RegisterDb(ksync_->agent()->vrf_assign_table()); 192 2 : } 193 : 194 0 : KSyncEntry *VrfAssignKSyncObject::Alloc(const KSyncEntry *ke, uint32_t index) { 195 0 : const VrfAssignKSyncEntry *rule = 196 : static_cast<const VrfAssignKSyncEntry *>(ke); 197 0 : VrfAssignKSyncEntry *ksync = new VrfAssignKSyncEntry(this, rule, index); 198 0 : return static_cast<KSyncEntry *>(ksync); 199 : } 200 : 201 0 : KSyncEntry *VrfAssignKSyncObject::DBToKSyncEntry(const DBEntry *e) { 202 0 : const VrfAssign *rule = static_cast<const VrfAssign *>(e); 203 0 : VrfAssignKSyncEntry *key = new VrfAssignKSyncEntry(this, rule); 204 0 : return static_cast<KSyncEntry *>(key); 205 : } 206 : 207 0 : void vr_vrf_assign_req::Process(SandeshContext *context) { 208 0 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context); 209 0 : ioc->VrfAssignMsgHandler(this); 210 0 : }