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