Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include <base/logging.h> 6 : #include <ksync/ksync_index.h> 7 : #include <ksync/ksync_entry.h> 8 : #include <ksync/ksync_object.h> 9 : #include <ksync/ksync_netlink.h> 10 : #include <ksync/ksync_sock.h> 11 : #include <vrouter/ksync/ksync_init.h> 12 : #include "vrouter/ksync/qos_queue_ksync.h" 13 : #include "vrouter/ksync/forwarding_class_ksync.h" 14 : 15 0 : QosConfigKSyncEntry::QosConfigKSyncEntry( 16 0 : QosConfigKSyncObject *obj, const QosConfigKSyncEntry *qc): 17 0 : KSyncNetlinkDBEntry(), ksync_obj_(obj), uuid_(qc->uuid()), id_(qc->id()) { 18 0 : } 19 : 20 0 : QosConfigKSyncEntry::QosConfigKSyncEntry(QosConfigKSyncObject *obj, 21 0 : const AgentQosConfig *qc): 22 0 : KSyncNetlinkDBEntry(), ksync_obj_(obj), uuid_(qc->uuid()), id_(qc->id()) { 23 0 : } 24 : 25 0 : QosConfigKSyncEntry::~QosConfigKSyncEntry() { 26 0 : } 27 : 28 0 : KSyncDBObject *QosConfigKSyncEntry::GetObject() const { 29 0 : return ksync_obj_; 30 : } 31 : 32 0 : bool QosConfigKSyncEntry::IsLess(const KSyncEntry &rhs) const { 33 0 : const QosConfigKSyncEntry &entry = static_cast<const QosConfigKSyncEntry &>(rhs); 34 0 : return uuid_ < entry.uuid_; 35 : } 36 : 37 0 : std::string QosConfigKSyncEntry::ToString() const { 38 0 : std::stringstream s; 39 0 : s << "Qos Config class id " << uuid_; 40 0 : return s.str(); 41 0 : } 42 : 43 0 : bool QosConfigKSyncEntry::CopyQosMap(KSyncQosFcMap &ksync_map, 44 : const AgentQosConfig:: 45 : QosIdForwardingClassMap *map) { 46 : 47 0 : bool ret = false; 48 : ForwardingClassKSyncObject *fc_object = 49 0 : static_cast<ForwardingClassKSyncObject *>(ksync_obj_) 50 0 : ->ksync()->forwarding_class_ksync_obj(); 51 : 52 0 : KSyncQosFcMap new_ksync_map; 53 0 : AgentQosConfig::QosIdForwardingClassMap::const_iterator it = map->begin(); 54 0 : for (; it != map->end(); it++) { 55 0 : KSyncEntryPtr ptr(NULL); 56 0 : ForwardingClassKSyncEntry fc_key(fc_object, it->second); 57 0 : ptr = fc_object->GetReference(&fc_key); 58 0 : new_ksync_map.insert(KSyncQosFcPair(it->first, ptr)); 59 0 : } 60 : 61 0 : if (ksync_map != new_ksync_map) { 62 0 : ksync_map = new_ksync_map; 63 0 : ret = true; 64 : } 65 : 66 0 : return ret; 67 0 : } 68 : 69 0 : bool QosConfigKSyncEntry::Sync(DBEntry *e) { 70 0 : AgentQosConfig *qc = static_cast<AgentQosConfig *>(e); 71 0 : bool ret = false; 72 : 73 : 74 0 : if (CopyQosMap(dscp_map_, &(qc->dscp_map()))) { 75 0 : ret = true; 76 : } 77 : 78 0 : if (CopyQosMap(vlan_priority_map_, &(qc->vlan_priority_map()))) { 79 0 : ret = true; 80 : } 81 : 82 0 : if (CopyQosMap(mpls_exp_map_, &(qc->mpls_exp_map()))) { 83 0 : ret = true; 84 : } 85 : 86 0 : if (default_forwarding_class_ != qc->default_forwarding_class()) { 87 0 : default_forwarding_class_ = qc->default_forwarding_class(); 88 0 : ret = true; 89 : } 90 : 91 0 : return ret; 92 : } 93 : 94 0 : int QosConfigKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) { 95 0 : vr_qos_map_req encoder; 96 : 97 0 : encoder.set_h_op(op); 98 0 : encoder.set_qmr_id(id_); 99 0 : encoder.set_qmr_rid(0); 100 : 101 0 : std::vector<int8_t> key; 102 0 : std::vector<int8_t> data; 103 0 : KSyncQosFcMap::const_iterator it = dscp_map_.begin(); 104 0 : for (uint32_t index = 0; 105 0 : index <= AgentQosConfigTable::kDscpEntries; index++) { 106 0 : it = dscp_map_.find(index); 107 0 : if (it != dscp_map_.end()) { 108 : ForwardingClassKSyncEntry *fc = 109 0 : static_cast<ForwardingClassKSyncEntry *>(it->second.get()); 110 0 : key.push_back(index); 111 0 : data.push_back(fc->id()); 112 : } else { 113 0 : key.push_back(index); 114 0 : data.push_back(default_forwarding_class_); 115 : } 116 : } 117 : 118 0 : encoder.set_qmr_dscp(key); 119 0 : encoder.set_qmr_dscp_fc_id(data); 120 : 121 0 : std::vector<int8_t> vlan_key; 122 0 : std::vector<int8_t> vlan_data; 123 0 : it = vlan_priority_map_.begin(); 124 0 : for (uint32_t index = 0; 125 0 : index <= AgentQosConfigTable::k801pEntries; index++) { 126 0 : it = vlan_priority_map_.find(index); 127 0 : if (it != vlan_priority_map_.end()) { 128 : ForwardingClassKSyncEntry *fc = 129 0 : static_cast<ForwardingClassKSyncEntry *>(it->second.get()); 130 0 : vlan_key.push_back(index); 131 0 : vlan_data.push_back(fc->id()); 132 : } else { 133 0 : vlan_key.push_back(index); 134 0 : vlan_data.push_back(default_forwarding_class_); 135 : } 136 : } 137 0 : encoder.set_qmr_dotonep(vlan_key); 138 0 : encoder.set_qmr_dotonep_fc_id(vlan_data); 139 : 140 0 : std::vector<int8_t> mpls_key; 141 0 : std::vector<int8_t> mpls_data; 142 0 : it = mpls_exp_map_.begin(); 143 0 : for (uint32_t index = 0; 144 0 : index <= AgentQosConfigTable::kExpEntries; index++) { 145 0 : it = mpls_exp_map_.find(index); 146 0 : if (it != mpls_exp_map_.end()) { 147 : ForwardingClassKSyncEntry *fc = 148 0 : static_cast<ForwardingClassKSyncEntry *>(it->second.get()); 149 0 : mpls_key.push_back(index); 150 0 : mpls_data.push_back(fc->id()); 151 : } else { 152 0 : mpls_key.push_back(index); 153 0 : mpls_data.push_back(default_forwarding_class_); 154 : } 155 : } 156 0 : encoder.set_qmr_mpls_qos(mpls_key); 157 0 : encoder.set_qmr_mpls_qos_fc_id(mpls_data); 158 : 159 0 : int error = 0; 160 0 : int encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error); 161 0 : assert(error == 0); 162 0 : assert(encode_len <= buf_len); 163 0 : return encode_len; 164 0 : } 165 : 166 0 : int QosConfigKSyncEntry::AddMsg(char *buf, int buf_len) { 167 0 : return Encode(sandesh_op::ADD, buf, buf_len); 168 : } 169 : 170 0 : int QosConfigKSyncEntry::ChangeMsg(char *buf, int buf_len) { 171 0 : return Encode(sandesh_op::ADD, buf, buf_len); 172 : } 173 : 174 0 : int QosConfigKSyncEntry::DeleteMsg(char *buf, int buf_len) { 175 0 : return Encode(sandesh_op::DEL, buf, buf_len); 176 : } 177 : 178 0 : KSyncEntry *QosConfigKSyncEntry::UnresolvedReference() { 179 : 180 : //QOS config has forwarding-class ID 181 : //And qos-config may have a forwarding-class ID which 182 : //is not present, in that case unresolved dependency 183 : //would never resolve and all dependent object like 184 : //VMI also would not be programmed. vrouter also 185 : //doesnt cross check for forwarding-class 186 : //Hence not checking for any forwarding class reference 187 0 : return NULL; 188 : 189 : KSyncQosFcMap::const_iterator it = dscp_map_.begin(); 190 : for (; it != dscp_map_.end(); it++) { 191 : if (it->second.get()->IsResolved() == false) { 192 : return it->second.get(); 193 : } 194 : } 195 : 196 : it = vlan_priority_map_.begin(); 197 : for (; it != vlan_priority_map_.end(); it++) { 198 : if (it->second.get()->IsResolved() == false) { 199 : return it->second.get(); 200 : } 201 : } 202 : 203 : it = mpls_exp_map_.begin(); 204 : for (; it != mpls_exp_map_.end(); it++) { 205 : if (it->second.get()->IsResolved() == false) { 206 : return it->second.get(); 207 : } 208 : } 209 : 210 : if (default_forwarding_class_) { 211 : ForwardingClassKSyncObject *fc_object = 212 : static_cast<ForwardingClassKSyncObject *>(ksync_obj_) 213 : ->ksync()->forwarding_class_ksync_obj(); 214 : ForwardingClassKSyncEntry fc_key(fc_object, 215 : default_forwarding_class_); 216 : KSyncEntryPtr ptr = fc_object->GetReference(&fc_key); 217 : if (ptr && ptr->IsResolved() == false) { 218 : return ptr.get(); 219 : } 220 : } 221 : 222 : return NULL; 223 : } 224 : 225 3 : QosConfigKSyncObject::QosConfigKSyncObject(KSync *ksync): 226 3 : KSyncDBObject("KSync Qos Config class object"), ksync_(ksync) { 227 3 : } 228 : 229 6 : QosConfigKSyncObject::~QosConfigKSyncObject() { 230 : 231 6 : } 232 : 233 0 : void QosConfigKSyncObject::RegisterDBClients() { 234 0 : RegisterDb(ksync_->agent()->qos_config_table()); 235 0 : } 236 : 237 : KSyncEntry* 238 0 : QosConfigKSyncObject::Alloc(const KSyncEntry *e, uint32_t index) { 239 0 : const QosConfigKSyncEntry *entry = 240 : static_cast<const QosConfigKSyncEntry *>(e); 241 : QosConfigKSyncEntry *new_entry = 242 0 : new QosConfigKSyncEntry(this, entry); 243 0 : return static_cast<KSyncEntry *>(new_entry); 244 : } 245 : 246 0 : KSyncEntry *QosConfigKSyncObject::DBToKSyncEntry(const DBEntry *e) { 247 0 : const AgentQosConfig *qc = static_cast<const AgentQosConfig *>(e); 248 0 : QosConfigKSyncEntry *entry = new QosConfigKSyncEntry(this, qc); 249 0 : return static_cast<KSyncEntry *>(entry); 250 : } 251 : 252 0 : void vr_qos_map_req::Process(SandeshContext *context) { 253 0 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context); 254 0 : ioc->QosConfigMsgHandler(this); 255 0 : }