Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <sys/types.h>
6 : #include <net/ethernet.h>
7 : #include <boost/asio.hpp>
8 : #include <boost/bind/bind.hpp>
9 :
10 : #include <base/logging.h>
11 : #include <db/db_entry.h>
12 : #include <db/db_table.h>
13 : #include <db/db_table_partition.h>
14 : #include <ksync/ksync_index.h>
15 : #include <ksync/ksync_entry.h>
16 : #include <ksync/ksync_object.h>
17 : #include <ksync/ksync_netlink.h>
18 : #include <ksync/ksync_sock.h>
19 :
20 : #include "oper/interface_common.h"
21 : #include "oper/nexthop.h"
22 : #include "oper/mirror_table.h"
23 : #include "oper/tunnel_nh.h"
24 : #include "vrouter/ksync/nexthop_ksync.h"
25 : #include "vrouter/ksync/ksync_init.h"
26 : #include "vr_types.h"
27 : #include "oper/ecmp_load_balance.h"
28 : #include "vrouter/ksync/agent_ksync_types.h"
29 : #include <vrouter/ksync/ksync_agent_sandesh.h>
30 :
31 : using namespace boost::placeholders;
32 :
33 423 : NHKSyncEntry::NHKSyncEntry(NHKSyncObject *obj, const NHKSyncEntry *entry,
34 423 : uint32_t index) :
35 423 : KSyncNetlinkDBEntry(index), ksync_obj_(obj), type_(entry->type_),
36 423 : vrf_id_(entry->vrf_id_), label_(entry->label_),
37 423 : interface_(entry->interface_), sip_(entry->sip_), dip_(entry->dip_),
38 423 : sport_(entry->sport_), dport_(entry->dport_), smac_(entry->smac_),
39 423 : dmac_(entry->dmac_), rewrite_dmac_(entry->rewrite_dmac_),
40 423 : valid_(entry->valid_), policy_(entry->policy_),
41 423 : is_mcast_nh_(entry->is_mcast_nh_),
42 423 : defer_(entry->defer_), component_nh_list_(entry->component_nh_list_),
43 423 : nh_(entry->nh_), vlan_tag_(entry->vlan_tag_),
44 423 : is_local_ecmp_nh_(entry->is_local_ecmp_nh_),
45 423 : is_bridge_(entry->is_bridge_),
46 423 : is_vxlan_routing_(entry->is_vxlan_routing_),
47 423 : comp_type_(entry->comp_type_),
48 423 : validate_mcast_src_(entry->validate_mcast_src_),
49 423 : tunnel_type_(entry->tunnel_type_), prefix_len_(entry->prefix_len_),
50 423 : nh_id_(entry->nh_id()),
51 423 : component_nh_key_list_(entry->component_nh_key_list_),
52 423 : bridge_nh_(entry->bridge_nh_),
53 423 : flood_unknown_unicast_(entry->flood_unknown_unicast_),
54 423 : ecmp_hash_fieds_(entry->ecmp_hash_fieds_.HashFieldsToUse()),
55 423 : pbb_child_nh_(entry->pbb_child_nh_), isid_(entry->isid_),
56 423 : pbb_label_(entry->pbb_label_), learning_enabled_(entry->learning_enabled_),
57 423 : need_pbb_tunnel_(entry->need_pbb_tunnel_), etree_leaf_(entry->etree_leaf_),
58 423 : layer2_control_word_(entry->layer2_control_word_),
59 423 : crypt_(entry->crypt_), crypt_path_available_(entry->crypt_path_available_),
60 423 : crypt_interface_(entry->crypt_interface_),
61 423 : transport_tunnel_type_(entry->transport_tunnel_type_),
62 423 : interface_list_(entry->interface_list_),
63 423 : encap_valid_list_(entry->encap_valid_list_),
64 846 : dmac_list_(entry->dmac_list_) {
65 423 : }
66 :
67 2830 : NHKSyncEntry::NHKSyncEntry(NHKSyncObject *obj, const NextHop *nh) :
68 5660 : KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj), type_(nh->GetType()),
69 8490 : vrf_id_(0), interface_(NULL), dmac_(), valid_(nh->IsValid()),
70 2830 : policy_(nh->PolicyEnabled()), is_mcast_nh_(false), nh_(nh),
71 2830 : vlan_tag_(VmInterface::kInvalidVlanId), is_bridge_(false),
72 2830 : is_vxlan_routing_(false),
73 2830 : tunnel_type_(TunnelType::INVALID), prefix_len_(32), nh_id_(nh->id()),
74 2830 : bridge_nh_(false), flood_unknown_unicast_(false),
75 2830 : learning_enabled_(nh->learning_enabled()), need_pbb_tunnel_(false),
76 2830 : etree_leaf_ (false), layer2_control_word_(false),
77 2830 : crypt_(false), crypt_path_available_(false), crypt_interface_(NULL),
78 16980 : interface_list_(), encap_valid_list_(), dmac_list_() {
79 :
80 2830 : switch (type_) {
81 25 : case NextHop::ARP: {
82 25 : const ArpNH *arp = static_cast<const ArpNH *>(nh);
83 25 : vrf_id_ = arp->vrf_id();
84 25 : sip_ = *(arp->GetIp());
85 25 : break;
86 : }
87 :
88 0 : case NextHop::NDP: {
89 0 : const NdpNH *ndp = static_cast<const NdpNH *>(nh);
90 0 : vrf_id_ = ndp->vrf_id();
91 0 : sip_ = *(ndp->GetIp());
92 0 : break;
93 : }
94 :
95 1527 : case NextHop::INTERFACE: {
96 : InterfaceKSyncObject *interface_object =
97 1527 : ksync_obj_->ksync()->interface_ksync_obj();
98 1527 : const InterfaceNH *if_nh = static_cast<const InterfaceNH *>(nh);
99 1527 : InterfaceKSyncEntry if_ksync(interface_object, if_nh->GetInterface());
100 1527 : interface_ = interface_object->GetReference(&if_ksync);
101 1527 : assert(interface_);
102 1527 : is_mcast_nh_ = if_nh->is_multicastNH();
103 1527 : is_bridge_ = if_nh->IsBridge();
104 1527 : is_vxlan_routing_ = if_nh->IsVxlanRouting();
105 1527 : const VrfEntry * vrf = if_nh->GetVrf();
106 1527 : vrf_id_ = (vrf != NULL) ? vrf->vrf_id() : VrfEntry::kInvalidIndex;
107 1527 : dmac_ = if_nh->GetDMac();
108 : // VmInterface can potentially have vlan-tags. Get tag in such case
109 1527 : if (if_nh->GetInterface()->type() == Interface::VM_INTERFACE) {
110 1399 : vlan_tag_ = (static_cast<const VmInterface *>
111 1399 : (if_nh->GetInterface()))->tx_vlan_id();
112 : }
113 1527 : break;
114 1527 : }
115 :
116 0 : case NextHop::VLAN: {
117 : InterfaceKSyncObject *interface_object =
118 0 : ksync_obj_->ksync()->interface_ksync_obj();
119 0 : const VlanNH *vlan_nh = static_cast<const VlanNH *>(nh);
120 0 : InterfaceKSyncEntry if_ksync(interface_object, vlan_nh->GetInterface());
121 0 : interface_ = interface_object->GetReference(&if_ksync);
122 0 : assert(interface_);
123 0 : vlan_tag_ = vlan_nh->GetVlanTag();
124 0 : vrf_id_ = vlan_nh->GetVrf()->vrf_id();
125 0 : break;
126 0 : }
127 :
128 101 : case NextHop::TUNNEL: {
129 101 : const TunnelNH *tunnel = static_cast<const TunnelNH *>(nh);
130 101 : vrf_id_ = tunnel->vrf_id();
131 101 : sip_ = *(tunnel->GetSip());
132 101 : dip_ = *(tunnel->GetDip());
133 101 : tunnel_type_ = tunnel->GetTunnelType();
134 101 : crypt_ = tunnel->GetCrypt();
135 101 : crypt_path_available_ = tunnel->GetCryptTunnelAvailable();
136 :
137 101 : if (tunnel->GetCryptInterface()) {
138 : InterfaceKSyncObject *crypt_interface_object =
139 0 : ksync_obj_->ksync()->interface_ksync_obj();
140 0 : InterfaceKSyncEntry if_ksync(crypt_interface_object, tunnel->GetCryptInterface());
141 0 : crypt_interface_ = crypt_interface_object->GetReference(&if_ksync);
142 0 : }
143 101 : rewrite_dmac_ = tunnel->rewrite_dmac();
144 101 : if (tunnel_type_.GetType() == TunnelType::MPLS_OVER_MPLS) {
145 0 : const LabelledTunnelNH *labelled_tunnel =
146 : static_cast<const LabelledTunnelNH *>(nh);
147 0 : label_ = labelled_tunnel->GetTransportLabel();
148 0 : transport_tunnel_type_ =
149 0 : labelled_tunnel->GetTransportTunnelType();
150 : }
151 101 : break;
152 : }
153 :
154 48 : case NextHop::DISCARD: {
155 48 : break;
156 : }
157 :
158 112 : case NextHop::L2_RECEIVE: {
159 112 : break;
160 : }
161 :
162 10 : case NextHop::RESOLVE: {
163 : InterfaceKSyncObject *interface_object =
164 10 : ksync_obj_->ksync()->interface_ksync_obj();
165 10 : const ResolveNH *rsl_nh = static_cast<const ResolveNH *>(nh);
166 10 : InterfaceKSyncEntry if_ksync(interface_object, rsl_nh->get_interface());
167 10 : interface_ = interface_object->GetReference(&if_ksync);
168 10 : vrf_id_ = rsl_nh->get_interface()->vrf_id();
169 10 : if (rsl_nh->get_interface()->type() == Interface::VM_INTERFACE) {
170 : const VmInterface *vm_intf =
171 10 : static_cast<const VmInterface *>(rsl_nh->get_interface());
172 10 : if (vm_intf->vrf()->forwarding_vrf()) {
173 10 : vrf_id_ = vm_intf->vrf()->forwarding_vrf()->vrf_id();
174 : }
175 : }
176 10 : break;
177 10 : }
178 :
179 59 : case NextHop::VRF: {
180 59 : const VrfNH *vrf_nh = static_cast<const VrfNH *>(nh);
181 59 : vrf_id_ = vrf_nh->GetVrf()->vrf_id();
182 59 : bridge_nh_ = vrf_nh->bridge_nh();
183 59 : break;
184 : }
185 :
186 31 : case NextHop::RECEIVE: {
187 : InterfaceKSyncObject *interface_object =
188 31 : ksync_obj_->ksync()->interface_ksync_obj();
189 31 : const ReceiveNH *rcv_nh = static_cast<const ReceiveNH *>(nh);
190 31 : InterfaceKSyncEntry if_ksync(interface_object, rcv_nh->GetInterface());
191 31 : interface_ = interface_object->GetReference(&if_ksync);
192 31 : vrf_id_ = rcv_nh->GetInterface()->vrf_id();
193 31 : assert(interface_);
194 31 : break;
195 31 : }
196 :
197 0 : case NextHop::MIRROR: {
198 0 : const MirrorNH *mirror_nh = static_cast<const MirrorNH *>(nh);
199 0 : vrf_id_ = mirror_nh->vrf_id();
200 0 : sip_ = *(mirror_nh->GetSip());
201 0 : sport_ = mirror_nh->GetSPort();
202 0 : dip_ = *(mirror_nh->GetDip());
203 0 : dport_ = mirror_nh->GetDPort();
204 0 : break;
205 : }
206 :
207 0 : case NextHop::PBB: {
208 0 : const PBBNH *pbb_nh = static_cast<const PBBNH *>(nh);
209 0 : vrf_id_ = pbb_nh->vrf_id();
210 0 : dmac_ = pbb_nh->dest_bmac();
211 0 : isid_ = pbb_nh->isid();
212 0 : break;
213 : }
214 :
215 917 : case NextHop::COMPOSITE: {
216 917 : const CompositeNH *comp_nh = static_cast<const CompositeNH *>(nh);
217 917 : component_nh_list_.clear();
218 917 : vrf_id_ = comp_nh->vrf()->vrf_id();
219 917 : comp_type_ = comp_nh->composite_nh_type();
220 917 : validate_mcast_src_ = comp_nh->validate_mcast_src();
221 917 : ecmp_hash_fieds_ =
222 917 : const_cast<CompositeNH *>(comp_nh)->CompEcmpHashFields().HashFieldsToUse();
223 917 : component_nh_key_list_ = comp_nh->component_nh_key_list();
224 : ComponentNHList::const_iterator component_nh_it =
225 917 : comp_nh->begin();
226 2010 : while (component_nh_it != comp_nh->end()) {
227 1093 : const NextHop *component_nh = NULL;
228 1093 : uint32_t label = 0;
229 1093 : if (*component_nh_it) {
230 1093 : component_nh = (*component_nh_it)->nh();
231 1093 : label = (*component_nh_it)->label();
232 : }
233 1093 : KSyncEntry *ksync_nh = NULL;
234 1093 : if (component_nh != NULL) {
235 : NHKSyncObject *nh_object =
236 1093 : ksync_obj_->ksync()->nh_ksync_obj();
237 1093 : NHKSyncEntry nhksync(nh_object, component_nh);
238 1093 : ksync_nh = nh_object->GetReference(&nhksync);
239 1093 : }
240 1093 : KSyncComponentNH ksync_component_nh(label, ksync_nh);
241 1093 : component_nh_list_.push_back(ksync_component_nh);
242 1093 : component_nh_it++;
243 1093 : }
244 917 : break;
245 : }
246 :
247 0 : default:
248 0 : assert(0);
249 : break;
250 : }
251 2830 : }
252 :
253 4099 : NHKSyncEntry::~NHKSyncEntry() {
254 4099 : }
255 :
256 5614 : KSyncDBObject *NHKSyncEntry::GetObject() const {
257 5614 : return ksync_obj_;
258 : }
259 :
260 24860 : bool NHKSyncEntry::IsLess(const KSyncEntry &rhs) const {
261 24860 : const NHKSyncEntry &entry = static_cast<const NHKSyncEntry &>(rhs);
262 :
263 24860 : if (type_ != entry.type_) {
264 6836 : return type_ < entry.type_;
265 : }
266 :
267 18024 : if (type_ == NextHop::DISCARD) {
268 96 : return false;
269 : }
270 :
271 17928 : if (type_ == NextHop::L2_RECEIVE) {
272 224 : return false;
273 : }
274 :
275 17704 : if (type_ == NextHop::ARP || type_ == NextHop::NDP) {
276 : //Policy is ignored for ARP NH
277 50 : if (vrf_id_ != entry.vrf_id_) {
278 0 : return vrf_id_ < entry.vrf_id_;
279 : }
280 50 : return sip_ < entry.sip_;
281 : }
282 :
283 17654 : if (policy_ != entry.policy_) {
284 2084 : return policy_ < entry.policy_;
285 : }
286 :
287 15570 : if (type_ == NextHop::VRF) {
288 181 : if ( vrf_id_ != entry.vrf_id_) {
289 63 : return vrf_id_ < entry.vrf_id_;
290 : }
291 118 : return bridge_nh_ < entry.bridge_nh_;
292 : }
293 :
294 15389 : if (type_ == NextHop::INTERFACE) {
295 9990 : if (is_mcast_nh_ != entry.is_mcast_nh_) {
296 1411 : return is_mcast_nh_ < entry.is_mcast_nh_;
297 : }
298 8579 : if(is_bridge_ != entry.is_bridge_) {
299 2165 : return is_bridge_ < entry.is_bridge_;
300 : }
301 :
302 6414 : if(is_vxlan_routing_ != entry.is_vxlan_routing_) {
303 0 : return is_vxlan_routing_ < entry.is_vxlan_routing_;
304 : }
305 :
306 6414 : if (dmac_ != entry.dmac_) {
307 3083 : return dmac_ < entry.dmac_;
308 : }
309 :
310 3331 : return interface() < entry.interface();
311 : }
312 :
313 5399 : if (type_ == NextHop::RECEIVE || type_ == NextHop::RESOLVE) {
314 82 : return interface() < entry.interface();
315 : }
316 :
317 :
318 5317 : if (type_ == NextHop::TUNNEL) {
319 257 : if (vrf_id_ != entry.vrf_id_) {
320 0 : return vrf_id_ < entry.vrf_id_;
321 : }
322 :
323 257 : if (sip_ != entry.sip_) {
324 0 : return sip_ < entry.sip_;
325 : }
326 :
327 257 : if (dip_ != entry.dip_) {
328 39 : return dip_ < entry.dip_;
329 : }
330 :
331 218 : if (crypt_ != entry.crypt_) {
332 0 : return crypt_ < entry.crypt_;
333 : }
334 :
335 218 : if (crypt_path_available_ != entry.crypt_path_available_) {
336 0 : return crypt_path_available_ < entry.crypt_path_available_;
337 : }
338 :
339 218 : if (crypt_interface() != entry.crypt_interface()) {
340 0 : return crypt_interface() < entry.crypt_interface();
341 : }
342 :
343 218 : if (rewrite_dmac_ != entry.rewrite_dmac_) {
344 0 : return rewrite_dmac_ < entry.rewrite_dmac_;
345 : }
346 218 : if (tunnel_type_.Compare(entry.tunnel_type_) == false) {
347 16 : return tunnel_type_.IsLess(entry.tunnel_type_);
348 : }
349 202 : if (tunnel_type_.GetType() == TunnelType::MPLS_OVER_MPLS) {
350 0 : return label_ < entry.label_;
351 : }
352 : }
353 :
354 5262 : if (type_ == NextHop::MIRROR) {
355 0 : if (vrf_id_ != entry.vrf_id_) {
356 0 : return vrf_id_ < entry.vrf_id_;
357 : }
358 :
359 0 : if (dip_ != entry.dip_) {
360 0 : return dip_ < entry.dip_;
361 : }
362 :
363 0 : return dport_ < entry.dport_;
364 : }
365 :
366 5262 : if (type_ == NextHop::PBB) {
367 0 : if (vrf_id_ != entry.vrf_id_) {
368 0 : return vrf_id_ < entry.vrf_id_;
369 : }
370 :
371 0 : if (dmac_ != entry.dmac_) {
372 0 : return dmac_ < entry.dmac_;
373 : }
374 :
375 0 : return isid_ < entry.isid_;
376 : }
377 :
378 5262 : if (type_ == NextHop::COMPOSITE) {
379 5060 : if (comp_type_ != entry.comp_type_) {
380 1537 : return comp_type_ < entry.comp_type_;
381 : }
382 :
383 3523 : if (vrf_id_ != entry.vrf_id_) {
384 659 : return vrf_id_ < entry.vrf_id_;
385 : }
386 :
387 : ComponentNHKeyList::const_iterator it =
388 2864 : component_nh_key_list_.begin();
389 : ComponentNHKeyList::const_iterator entry_it =
390 2864 : entry.component_nh_key_list_.begin();
391 8549 : for (;it != component_nh_key_list_.end() &&
392 11061 : entry_it != entry.component_nh_key_list_.end(); it++, entry_it++) {
393 3053 : if (*it == NULL &&
394 0 : *entry_it == NULL) {
395 0 : continue;
396 : }
397 : //One of the component NH is NULL
398 6106 : if ((*it) == NULL ||
399 3053 : (*entry_it) == NULL) {
400 0 : return (*it) < (*entry_it);
401 : }
402 :
403 : //Check if the label is different
404 6106 : if ((*it)->label() !=
405 3053 : (*entry_it)->label()) {
406 0 : return (*it)->label() <
407 0 : (*entry_it)->label();
408 : }
409 :
410 : //Check if the nexthop key is different
411 : //Ideally we could find the nexthop and compare pointer alone
412 : //it wont work because this is called from Find context itself,
413 : //and it would result in deadlock
414 : //Hence compare nexthop key alone
415 3053 : const NextHopKey *left_nh = (*it)->nh_key();
416 3053 : const NextHopKey *right_nh = (*entry_it)->nh_key();
417 :
418 3053 : if (left_nh->IsEqual(*right_nh) == false) {
419 541 : if (left_nh->GetType() != right_nh->GetType()) {
420 0 : return left_nh->GetType() < right_nh->GetType();
421 : }
422 541 : return left_nh->IsLess(*right_nh);
423 : }
424 :
425 : }
426 :
427 4526 : if (it == component_nh_key_list_.end() &&
428 4526 : entry_it == entry.component_nh_key_list_.end()) {
429 1834 : return false;
430 : }
431 :
432 489 : if (it == component_nh_key_list_.end()) {
433 369 : return true;
434 : }
435 120 : return false;
436 : }
437 :
438 202 : if (type_ == NextHop::VLAN) {
439 0 : if (interface() != entry.interface()) {
440 0 : return interface() < entry.interface();
441 :
442 : }
443 :
444 0 : return vlan_tag_ < entry.vlan_tag_;
445 : }
446 :
447 202 : return false;
448 :
449 : assert(0);
450 : }
451 :
452 9727 : std::string NHKSyncEntry::ToString() const {
453 9727 : std::stringstream s;
454 9727 : s << "NextHop Index: " << nh_id() << " Type: ";
455 9727 : switch(type_) {
456 97 : case NextHop::DISCARD: {
457 97 : s << "Discard";
458 97 : break;
459 : }
460 279 : case NextHop::L2_RECEIVE: {
461 279 : s << "L2-Receive ";
462 279 : break;
463 : }
464 86 : case NextHop::RECEIVE: {
465 86 : s << "Receive ";
466 86 : break;
467 : }
468 24 : case NextHop::RESOLVE: {
469 24 : s << "Resolve ";
470 24 : break;
471 : }
472 68 : case NextHop::ARP: {
473 68 : s << "ARP ";
474 68 : break;
475 : }
476 0 : case NextHop::NDP: {
477 0 : s << "NDP ";
478 0 : break;
479 : }
480 282 : case NextHop::VRF: {
481 282 : s << "VRF assign to ";
482 : const VrfEntry* vrf =
483 282 : ksync_obj_->ksync()->agent()->vrf_table()->
484 282 : FindVrfFromId(vrf_id_);
485 282 : if (vrf) {
486 183 : s << vrf->GetName() << " ";
487 : } else {
488 99 : s << "Invalid ";
489 : }
490 282 : break;
491 : }
492 5080 : case NextHop::INTERFACE: {
493 5080 : s << "Interface ";
494 5080 : break;
495 : }
496 356 : case NextHop::TUNNEL: {
497 356 : s << "Tunnel to ";
498 356 : s << dip_.to_string();
499 356 : s << "rewrite_dmac";
500 356 : s << rewrite_dmac_.ToString();
501 356 : break;
502 : }
503 0 : case NextHop::MIRROR: {
504 0 : s << "Mirror to ";
505 0 : s << dip_.to_string() << ": " << dport_;
506 0 : break;
507 : }
508 0 : case NextHop::VLAN: {
509 0 : s << "VLAN interface ";
510 0 : break;
511 : }
512 3455 : case NextHop::COMPOSITE: {
513 3455 : s << "Composite Child members: ";
514 3455 : if (component_nh_list_.size() == 0) {
515 380 : s << "Empty ";
516 : }
517 3455 : for (KSyncComponentNHList::const_iterator it = component_nh_list_.begin();
518 7453 : it != component_nh_list_.end(); it++) {
519 3998 : KSyncComponentNH component_nh = *it;
520 3998 : if (component_nh.nh()) {
521 3998 : s << component_nh.nh()->ToString();
522 : }
523 3998 : }
524 3455 : break;
525 : }
526 0 : case NextHop::INVALID: {
527 0 : s << "Invalid ";
528 : }
529 :
530 0 : case NextHop::PBB: {
531 0 : s << "PBB";
532 0 : break;
533 : }
534 : }
535 :
536 9727 : if (interface_) {
537 5190 : s << "<" << interface_->ToString() << ">";
538 : }
539 19454 : return s.str();
540 9727 : }
541 :
542 458 : bool NHKSyncEntry::Sync(DBEntry *e) {
543 458 : bool ret = false;
544 458 : const NextHop *nh = static_cast<NextHop *>(e);
545 :
546 458 : if (valid_ != nh->IsValid()) {
547 0 : valid_ = nh->IsValid();
548 0 : ret = true;
549 : }
550 :
551 458 : if (learning_enabled_ != nh->learning_enabled()) {
552 22 : learning_enabled_ = nh->learning_enabled();
553 22 : ret = true;
554 : }
555 :
556 458 : if (etree_leaf_ != nh->etree_leaf()) {
557 12 : etree_leaf_ = nh->etree_leaf();
558 12 : ret = true;
559 : }
560 :
561 458 : switch (nh->GetType()) {
562 4 : case NextHop::ARP: {
563 : InterfaceKSyncObject *interface_object =
564 4 : ksync_obj_->ksync()->interface_ksync_obj();
565 4 : ArpNH *arp_nh = static_cast<ArpNH *>(e);
566 4 : if (dmac_ != arp_nh->GetMac()) {
567 0 : dmac_ = arp_nh->GetMac();
568 0 : ret = true;
569 : }
570 :
571 4 : if (valid_) {
572 : InterfaceKSyncEntry if_ksync(interface_object,
573 0 : arp_nh->GetInterface());
574 0 : if (interface_ != interface_object->GetReference(&if_ksync)) {
575 0 : interface_ = interface_object->GetReference(&if_ksync);
576 0 : ret = true;
577 : }
578 0 : } else {
579 4 : if (interface_ != NULL) {
580 0 : interface_ = NULL;
581 0 : dmac_.Zero();
582 0 : ret = true;
583 : }
584 : }
585 4 : break;
586 : }
587 :
588 0 : case NextHop::NDP: {
589 : InterfaceKSyncObject *interface_object =
590 0 : ksync_obj_->ksync()->interface_ksync_obj();
591 0 : NdpNH *ndp_nh = static_cast<NdpNH *>(e);
592 0 : if (dmac_ != ndp_nh->GetMac()) {
593 0 : dmac_ = ndp_nh->GetMac();
594 0 : ret = true;
595 : }
596 :
597 0 : if (valid_) {
598 : InterfaceKSyncEntry if_ksync(interface_object,
599 0 : ndp_nh->GetInterface());
600 0 : if (interface_ != interface_object->GetReference(&if_ksync)) {
601 0 : interface_ = interface_object->GetReference(&if_ksync);
602 0 : ret = true;
603 : }
604 0 : } else {
605 0 : if (interface_ != NULL) {
606 0 : interface_ = NULL;
607 0 : dmac_.Zero();
608 0 : ret = true;
609 : }
610 : }
611 0 : break;
612 : }
613 :
614 214 : case NextHop::INTERFACE: {
615 214 : InterfaceNH *intf_nh = static_cast<InterfaceNH *>(e);
616 214 : dmac_ = intf_nh->GetDMac();
617 214 : uint16_t vlan_tag = VmInterface::kInvalidVlanId;
618 214 : if (intf_nh->GetInterface()->type() == Interface::VM_INTERFACE) {
619 203 : vlan_tag = vlan_tag_;
620 203 : vlan_tag_ = (static_cast<const VmInterface *>
621 203 : (intf_nh->GetInterface()))->tx_vlan_id();
622 203 : if (vlan_tag != vlan_tag_) {
623 0 : ret = true;
624 : }
625 : }
626 214 : if (layer2_control_word_ != intf_nh->layer2_control_word()) {
627 0 : layer2_control_word_ = intf_nh->layer2_control_word();
628 0 : ret = true;
629 : }
630 :
631 214 : const VrfEntry * vrf = intf_nh->GetVrf();
632 214 : uint32_t vrf_id = (vrf != NULL)? vrf->vrf_id() :VrfEntry::kInvalidIndex;
633 214 : if (vrf_id_ != vrf_id) {
634 0 : vrf_id_ = vrf_id;
635 0 : ret = true;
636 : }
637 214 : break;
638 : }
639 :
640 3 : case NextHop::DISCARD: {
641 3 : ret = false;
642 3 : break;
643 : }
644 :
645 3 : case NextHop::L2_RECEIVE: {
646 3 : ret = false;
647 3 : break;
648 : }
649 :
650 14 : case NextHop::TUNNEL: {
651 14 : ret = true;
652 :
653 : // If the nh IDs of KSyncEntry and NextHop objects dont match, sync them
654 : // along with nh_ pointer. It can happen if the NHKSyncEntry got
655 : // created in TEMP state with previous incarnation of this Tunnel NH
656 14 : if (nh_id_ != nh->id()) {
657 0 : nh_id_ = nh->id();
658 0 : nh_ = nh;
659 0 : ret = true;
660 : }
661 :
662 : // Invalid nexthop, no valid interface or mac info
663 : // present, just return
664 14 : if (valid_ == false) {
665 14 : if (interface_ != NULL) {
666 0 : interface_ = NULL;
667 0 : dmac_.Zero();
668 0 : ret = true;
669 : }
670 14 : break;
671 : }
672 :
673 0 : KSyncEntryPtr interface = NULL;
674 0 : MacAddress dmac;
675 0 : const TunnelNH *tun_nh = static_cast<TunnelNH *>(e);
676 0 : const NextHop *active_nh = tun_nh->GetRt()->GetActiveNextHop();
677 : // active nexthop can be NULL as when arp rt is delete marked and
678 : // is enqueued for notify.
679 0 : if (active_nh == NULL) {
680 0 : if (interface_ != NULL) {
681 0 : interface_ = NULL;
682 0 : dmac_.Zero();
683 0 : ret = true;
684 : }
685 0 : break;
686 : }
687 :
688 0 : if (active_nh->GetType() == NextHop::ARP) {
689 0 : const ArpNH *arp_nh = static_cast<const ArpNH *>(active_nh);
690 : InterfaceKSyncObject *interface_object =
691 0 : ksync_obj_->ksync()->interface_ksync_obj();
692 0 : InterfaceKSyncEntry if_ksync(interface_object, arp_nh->GetInterface());
693 0 : interface = interface_object->GetReference(&if_ksync);
694 0 : dmac = arp_nh->GetMac();
695 0 : } else if (active_nh->GetType() == NextHop::NDP) {
696 0 : const NdpNH *ndp_nh = static_cast<const NdpNH *>(active_nh);
697 : InterfaceKSyncObject *interface_object =
698 0 : ksync_obj_->ksync()->interface_ksync_obj();
699 0 : InterfaceKSyncEntry if_ksync(interface_object, ndp_nh->GetInterface());
700 0 : interface = interface_object->GetReference(&if_ksync);
701 0 : dmac = ndp_nh->GetMac();
702 0 : } else if (active_nh->GetType() == NextHop::INTERFACE) {
703 0 : const InterfaceNH *intf_nh =
704 : static_cast<const InterfaceNH *>(active_nh);
705 0 : const Interface *oper_intf = intf_nh->GetInterface();
706 : InterfaceKSyncObject *interface_object =
707 0 : ksync_obj_->ksync()->interface_ksync_obj();
708 0 : InterfaceKSyncEntry if_ksync(interface_object, oper_intf);
709 0 : interface = interface_object->GetReference(&if_ksync);
710 0 : dmac = oper_intf->mac();
711 0 : } else if (active_nh->GetType() == NextHop::COMPOSITE) {
712 0 : const CompositeNH *cnh =
713 : static_cast<const CompositeNH *>(active_nh);
714 0 : interface_list_.clear();
715 0 : encap_valid_list_.clear();
716 0 : dmac_list_.clear();
717 : ComponentNHList::const_iterator component_nh_it =
718 0 : cnh->begin();
719 0 : while (component_nh_it != cnh->end()) {
720 0 : const NextHop *component_nh = NULL;
721 0 : if (*component_nh_it) {
722 0 : component_nh = (*component_nh_it)->nh();
723 0 : if (component_nh->GetType() == NextHop::ARP) {
724 0 : const ArpNH *arp_nh = dynamic_cast<const ArpNH*>(component_nh);
725 : InterfaceKSyncObject *interface_object =
726 0 : ksync_obj_->ksync()->interface_ksync_obj();
727 0 : InterfaceKSyncEntry if_ksync(interface_object, arp_nh->GetInterface());
728 0 : interface_list_.push_back(interface_object->GetReference(&if_ksync));
729 0 : encap_valid_list_.push_back(arp_nh->IsValid());
730 0 : dmac_list_.push_back(arp_nh->GetMac());
731 0 : }
732 : }
733 0 : component_nh_it++;
734 : }
735 :
736 : /* vRouter expects encap_valid vector should always be size = 3.
737 : * It helps in accessing valid enacp_data and oif */
738 0 : while (encap_valid_list_.size() < MAX_VR_PHY_INTF) {
739 0 : encap_valid_list_.push_back(false);
740 : }
741 : }
742 :
743 0 : bool crypt = tun_nh->GetCrypt();
744 0 : if (crypt != crypt_) {
745 0 : crypt_ = crypt;
746 0 : ret = true;
747 : }
748 :
749 0 : bool crypt_path_available = tun_nh->GetCryptTunnelAvailable();
750 0 : if (crypt_path_available != crypt_path_available_) {
751 0 : crypt_path_available_ = crypt_path_available;
752 0 : ret = true;
753 : }
754 :
755 0 : const Interface *oper_crypt_intf = tun_nh->GetCryptInterface();
756 :
757 0 : if (tun_nh->GetCryptInterface()) {
758 : InterfaceKSyncObject *crypt_interface_object =
759 0 : ksync_obj_->ksync()->interface_ksync_obj();
760 0 : InterfaceKSyncEntry if_ksync(crypt_interface_object, oper_crypt_intf);
761 0 : KSyncEntryPtr crypt_interface = crypt_interface_object->GetReference(&if_ksync);
762 :
763 0 : if (crypt_interface != crypt_interface_) {
764 0 : crypt_interface_ = crypt_interface;
765 0 : ret = true;
766 : }
767 0 : }
768 0 : if (tunnel_type_.GetType() == TunnelType::MPLS_OVER_MPLS) {
769 0 : const LabelledTunnelNH *labelled_tunnel =
770 : static_cast<const LabelledTunnelNH *>(nh);
771 0 : if (label_ != labelled_tunnel->GetTransportLabel()) {
772 0 : label_ = labelled_tunnel->GetTransportLabel();
773 0 : ret = true;
774 : }
775 0 : if (transport_tunnel_type_ !=
776 0 : labelled_tunnel->GetTransportTunnelType()) {
777 0 : transport_tunnel_type_ =
778 0 : labelled_tunnel->GetTransportTunnelType();
779 0 : ret = true;
780 : }
781 : }
782 :
783 0 : if (dmac != dmac_) {
784 0 : dmac_ = dmac;
785 0 : ret = true;
786 : }
787 0 : if (interface_ != interface) {
788 0 : interface_ = interface;
789 0 : ret = true;
790 : }
791 0 : break;
792 0 : }
793 :
794 0 : case NextHop::MIRROR: {
795 0 : ret = true;
796 : // Invalid nexthop, no valid interface or mac info
797 : // present, just return
798 0 : if (valid_ == false || (vrf_id_ == (uint32_t)-1)) {
799 0 : if (interface_ != NULL) {
800 0 : interface_ = NULL;
801 0 : dmac_.Zero();
802 0 : ret = true;
803 : }
804 0 : break;
805 : }
806 :
807 0 : KSyncEntryPtr interface = NULL;
808 0 : MacAddress dmac;
809 0 : bool valid = valid_;
810 :
811 0 : const MirrorNH *mirror_nh = static_cast<MirrorNH *>(e);
812 0 : const NextHop *active_nh = mirror_nh->GetRt()->GetActiveNextHop();
813 0 : if (active_nh) {
814 0 : if (active_nh->GetType() == NextHop::ARP) {
815 0 : const ArpNH *arp_nh = static_cast<const ArpNH *>(active_nh);
816 : InterfaceKSyncObject *interface_object =
817 0 : ksync_obj_->ksync()->interface_ksync_obj();
818 : InterfaceKSyncEntry if_ksync(interface_object,
819 0 : arp_nh->GetInterface());
820 0 : interface = interface_object->GetReference(&if_ksync);
821 0 : dmac = arp_nh->GetMac();
822 0 : } else if (active_nh->GetType() == NextHop::NDP) {
823 0 : const NdpNH *ndp_nh = static_cast<const NdpNH *>(active_nh);
824 : InterfaceKSyncObject *interface_object =
825 0 : ksync_obj_->ksync()->interface_ksync_obj();
826 : InterfaceKSyncEntry if_ksync(interface_object,
827 0 : ndp_nh->GetInterface());
828 0 : interface = interface_object->GetReference(&if_ksync);
829 0 : dmac = ndp_nh->GetMac();
830 0 : } else if (active_nh->GetType() == NextHop::RECEIVE) {
831 0 : const ReceiveNH *rcv_nh = static_cast<const ReceiveNH *>(active_nh);
832 : InterfaceKSyncObject *interface_object =
833 0 : ksync_obj_->ksync()->interface_ksync_obj();
834 : InterfaceKSyncEntry if_ksync(interface_object,
835 0 : rcv_nh->GetInterface());
836 0 : interface = interface_object->GetReference(&if_ksync);
837 0 : Agent *agent = ksync_obj_->ksync()->agent();
838 0 : dmac = agent->vhost_interface()->mac();
839 0 : } else if (active_nh->GetType() == NextHop::DISCARD) {
840 0 : valid = false;
841 0 : interface = NULL;
842 : }
843 : } else {
844 0 : valid = false;
845 0 : interface = NULL;
846 : }
847 :
848 0 : if (valid_ != valid) {
849 0 : valid_ = valid;
850 0 : ret = true;
851 : }
852 0 : if (dmac_ != dmac) {
853 0 : dmac_ = dmac;
854 0 : ret = true;
855 : }
856 0 : if (interface_ != interface) {
857 0 : interface_ = interface;
858 0 : ret = true;
859 : }
860 0 : break;
861 0 : }
862 :
863 0 : case NextHop::PBB: {
864 0 : PBBNH *pbb_nh = static_cast<PBBNH *>(e);
865 0 : if (pbb_label_ != pbb_nh->label()) {
866 0 : pbb_label_ = pbb_nh->label();
867 0 : ret = true;
868 : }
869 :
870 : NHKSyncObject *nh_object =
871 0 : ksync_obj_->ksync()->nh_ksync_obj();
872 0 : NHKSyncEntry nhksync(nh_object, pbb_nh->child_nh());
873 0 : KSyncEntry *ksync_nh = nh_object->GetReference(&nhksync);
874 0 : if (ksync_nh != pbb_child_nh_) {
875 0 : pbb_child_nh_ = ksync_nh;
876 0 : ret = true;
877 : }
878 0 : break;
879 0 : }
880 :
881 186 : case NextHop::COMPOSITE: {
882 186 : ret = true;
883 186 : CompositeNH *comp_nh = static_cast<CompositeNH *>(e);
884 186 : component_nh_list_.clear();
885 : ComponentNHList::const_iterator component_nh_it =
886 186 : comp_nh->begin();
887 393 : while (component_nh_it != comp_nh->end()) {
888 207 : const NextHop *component_nh = NULL;
889 207 : uint32_t label = 0;
890 207 : if (*component_nh_it) {
891 207 : component_nh = (*component_nh_it)->nh();
892 207 : label = (*component_nh_it)->label();
893 : }
894 207 : KSyncEntry *ksync_nh = NULL;
895 207 : if (component_nh != NULL) {
896 : NHKSyncObject *nh_object =
897 207 : ksync_obj_->ksync()->nh_ksync_obj();
898 207 : NHKSyncEntry nhksync(nh_object, component_nh);
899 207 : ksync_nh = nh_object->GetReference(&nhksync);
900 207 : }
901 207 : KSyncComponentNH ksync_component_nh(label, ksync_nh);
902 207 : component_nh_list_.push_back(ksync_component_nh);
903 207 : component_nh_it++;
904 207 : }
905 :
906 186 : if (comp_nh->EcmpHashFieldInUse() != ecmp_hash_fieds_.HashFieldsToUse()) {
907 0 : ecmp_hash_fieds_ = comp_nh->CompEcmpHashFields().HashFieldsToUse();
908 0 : ret = true;
909 : }
910 :
911 186 : if (need_pbb_tunnel_ != comp_nh->pbb_nh()) {
912 75 : need_pbb_tunnel_ = comp_nh->pbb_nh();
913 75 : ret = true;
914 : }
915 :
916 186 : if (layer2_control_word_ != comp_nh->layer2_control_word()) {
917 0 : layer2_control_word_ = comp_nh->layer2_control_word();
918 0 : ret = true;
919 : }
920 186 : break;
921 : }
922 :
923 0 : case NextHop::VLAN: {
924 0 : VlanNH *vlan_nh = static_cast<VlanNH *>(e);
925 0 : smac_ = vlan_nh->GetSMac();
926 0 : dmac_ = vlan_nh->GetDMac();
927 0 : ret = false;
928 0 : break;
929 : }
930 :
931 25 : case NextHop::VRF: {
932 25 : VrfNH *vrf_nh = static_cast<VrfNH *>(e);
933 25 : vrf_id_ = vrf_nh->GetVrf()->vrf_id();
934 25 : ret = false;
935 25 : if (bridge_nh_ != vrf_nh->bridge_nh()) {
936 0 : bridge_nh_ = vrf_nh->bridge_nh();
937 0 : ret = true;
938 : }
939 :
940 25 : if (flood_unknown_unicast_ != vrf_nh->flood_unknown_unicast()) {
941 0 : flood_unknown_unicast_ = vrf_nh->flood_unknown_unicast();
942 0 : ret = true;
943 : }
944 :
945 25 : if (layer2_control_word_ != vrf_nh->layer2_control_word()) {
946 0 : layer2_control_word_ = vrf_nh->layer2_control_word();
947 0 : ret = true;
948 : }
949 25 : break;
950 : }
951 9 : case NextHop::RECEIVE:
952 : case NextHop::RESOLVE: {
953 9 : valid_ = true;
954 9 : ret = true;
955 9 : break;
956 : }
957 :
958 0 : default:
959 0 : assert(0);
960 : }
961 :
962 458 : return ret;
963 : };
964 878 : int NHKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
965 878 : vr_nexthop_req encoder;
966 : int encode_len;
967 878 : uint32_t crypt_intf_id = kInvalidIndex;
968 878 : uint32_t intf_id = kInvalidIndex;
969 878 : std::vector<int8_t> encap;
970 878 : InterfaceKSyncEntry *if_ksync = NULL;
971 878 : InterfaceKSyncEntry *crypt_if_ksync = NULL;
972 878 : std::vector<KSyncEntryPtr> if_ksync_list;
973 878 : std::vector<int32_t> nhr_encap_valid_list;
974 878 : std::vector<int32_t> intf_id_list;
975 878 : Agent *agent = ksync_obj_->ksync()->agent();
976 :
977 878 : encoder.set_h_op(op);
978 878 : encoder.set_nhr_id(nh_id());
979 878 : if (op == sandesh_op::DEL) {
980 : /* For delete only NH-index is required by vrouter */
981 423 : int error = 0;
982 423 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
983 423 : assert(error == 0);
984 423 : assert(encode_len <= buf_len);
985 423 : return encode_len;
986 : }
987 455 : encoder.set_nhr_rid(0);
988 455 : encoder.set_nhr_vrf(vrf_id_);
989 455 : encoder.set_nhr_family(AF_INET);
990 455 : uint32_t flags = 0;
991 455 : if (valid_) {
992 438 : flags |= NH_FLAG_VALID;
993 : }
994 :
995 455 : if (policy_) {
996 91 : flags |= NH_FLAG_POLICY_ENABLED;
997 : }
998 :
999 455 : if (etree_leaf_ == false) {
1000 443 : flags |= NH_FLAG_ETREE_ROOT;
1001 : }
1002 :
1003 455 : if (learning_enabled_) {
1004 10 : flags |= NH_FLAG_MAC_LEARN;
1005 : }
1006 :
1007 455 : if (layer2_control_word_) {
1008 0 : flags |= NH_FLAG_L2_CONTROL_DATA;
1009 : }
1010 :
1011 455 : if (crypt_) {
1012 0 : flags |= NH_FLAG_CRYPT_TRAFFIC;
1013 : }
1014 :
1015 455 : if_ksync = interface();
1016 455 : if_ksync_list = interface_list();
1017 455 : nhr_encap_valid_list = encap_valid_list();
1018 455 : crypt_if_ksync = crypt_interface();
1019 :
1020 455 : switch (type_) {
1021 217 : case NextHop::VLAN:
1022 : case NextHop::ARP:
1023 : case NextHop::NDP:
1024 : case NextHop::INTERFACE :
1025 217 : encoder.set_nhr_type(NH_ENCAP);
1026 217 : if (if_ksync) {
1027 214 : intf_id = if_ksync->interface_id();
1028 : }
1029 217 : encoder.set_nhr_encap_oif_id(std::vector<int32_t>(1, intf_id));
1030 217 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1031 :
1032 217 : SetEncap(if_ksync, encap);
1033 217 : encoder.set_nhr_encap(encap);
1034 217 : encoder.set_nhr_tun_sip(0);
1035 217 : encoder.set_nhr_tun_dip(0);
1036 217 : if (is_vxlan_routing_) {
1037 : //Set vxlan routing flag
1038 0 : flags |= NH_FLAG_L3_VXLAN;
1039 : }
1040 217 : if (is_bridge_) {
1041 90 : encoder.set_nhr_family(AF_BRIDGE);
1042 : }
1043 217 : if (is_mcast_nh_) {
1044 35 : flags |= NH_FLAG_MCAST;
1045 : }
1046 217 : encoder.set_nhr_flags(flags);
1047 217 : break;
1048 :
1049 14 : case NextHop::TUNNEL : {
1050 14 : encoder.set_nhr_type(NH_TUNNEL);
1051 14 : encoder.set_nhr_tun_sip(htonl(sip_.to_v4().to_ulong()));
1052 14 : encoder.set_nhr_tun_dip(htonl(dip_.to_v4().to_ulong()));
1053 14 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1054 :
1055 14 : if (if_ksync_list.empty() == false) {
1056 0 : flags |= NH_FLAG_TUNNEL_UNDERLAY_ECMP;
1057 0 : uint32_t encap_len = 0;
1058 0 : for (size_t i = 0; i < if_ksync_list.size(); ++i) {
1059 : InterfaceKSyncEntry *if_ksync_entry =
1060 0 : static_cast<InterfaceKSyncEntry *>(if_ksync_list[i].get());
1061 0 : intf_id_list.push_back(if_ksync_entry->interface_id());
1062 0 : encap_len = encap.size();
1063 0 : SetEncap(if_ksync_entry, encap, i);
1064 0 : encap_len = encap.size() - encap_len;
1065 : }
1066 0 : encoder.set_nhr_encap_len(encap_len);
1067 : } else {
1068 14 : SetEncap(if_ksync, encap);
1069 14 : intf_id_list.push_back(0);
1070 : }
1071 14 : encoder.set_nhr_encap_oif_id(intf_id_list);
1072 14 : encoder.set_nhr_encap_valid(nhr_encap_valid_list);
1073 14 : encoder.set_nhr_crypt_traffic(crypt_);
1074 14 : encoder.set_nhr_crypt_path_available(crypt_path_available_);
1075 14 : if (crypt_if_ksync && crypt_path_available_) {
1076 0 : crypt_intf_id = crypt_if_ksync->interface_id();
1077 : }
1078 14 : encoder.set_nhr_encap_crypt_oif_id(crypt_intf_id);
1079 14 : encoder.set_nhr_encap(encap);
1080 14 : if (tunnel_type_.GetType() == TunnelType::MPLS_UDP) {
1081 0 : flags |= NH_FLAG_TUNNEL_UDP_MPLS;
1082 14 : } else if (tunnel_type_.GetType() == TunnelType::MPLS_GRE) {
1083 10 : flags |= NH_FLAG_TUNNEL_GRE;
1084 4 : } else if (tunnel_type_.GetType() == TunnelType::NATIVE) {
1085 : //Ideally we should have created a new type of
1086 : //indirect nexthop to handle NATIVE encap
1087 : //reusing tunnel NH as it provides most of
1088 : //functionality now
1089 0 : encoder.set_nhr_type(NH_ENCAP);
1090 0 : encoder.set_nhr_encap_oif_id(intf_id_list);
1091 0 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1092 0 : encoder.set_nhr_tun_sip(0);
1093 0 : encoder.set_nhr_tun_dip(0);
1094 4 : } else if (tunnel_type_.GetType() == TunnelType::MPLS_OVER_MPLS) {
1095 0 : flags |= NH_FLAG_TUNNEL_MPLS_O_MPLS;
1096 0 : if (transport_tunnel_type_ == TunnelType::MPLS_UDP) {
1097 0 : flags |= NH_FLAG_TUNNEL_UDP_MPLS;
1098 : } else {
1099 0 : flags |= NH_FLAG_TUNNEL_GRE;
1100 : }
1101 :
1102 0 : encoder.set_nhr_transport_label(label_);
1103 : } else {
1104 4 : flags |= NH_FLAG_TUNNEL_VXLAN;
1105 : }
1106 14 : std::vector<int8_t> rewrite_dmac;
1107 98 : for (size_t i = 0 ; i < rewrite_dmac_.size(); i++) {
1108 84 : rewrite_dmac.push_back(rewrite_dmac_[i]);
1109 : }
1110 14 : encoder.set_nhr_rw_dst_mac(rewrite_dmac);
1111 : //TODO remove set_nhr_pbb_mac
1112 14 : encoder.set_nhr_pbb_mac(rewrite_dmac);
1113 14 : if (rewrite_dmac_.IsZero() == false) {
1114 0 : flags |= NH_FLAG_L3_VXLAN;
1115 : }
1116 14 : break;
1117 14 : }
1118 0 : case NextHop::MIRROR :
1119 0 : encoder.set_nhr_type(NH_TUNNEL);
1120 0 : if (sip_.is_v4() && dip_.is_v4()) {
1121 0 : encoder.set_nhr_tun_sip(htonl(sip_.to_v4().to_ulong()));
1122 0 : encoder.set_nhr_tun_dip(htonl(dip_.to_v4().to_ulong()));
1123 0 : } else if (sip_.is_v6() && dip_.is_v6()) {
1124 0 : encoder.set_nhr_family(AF_INET6);
1125 0 : Ip6Address::bytes_type bytes = sip_.to_v6().to_bytes();
1126 0 : std::vector<int8_t> sip_vector(bytes.begin(), bytes.end());
1127 0 : bytes = dip_.to_v6().to_bytes();
1128 0 : std::vector<int8_t> dip_vector(bytes.begin(), bytes.end());
1129 0 : encoder.set_nhr_tun_sip6(sip_vector);
1130 0 : encoder.set_nhr_tun_dip6(dip_vector);
1131 0 : }
1132 0 : encoder.set_nhr_tun_sport(htons(sport_));
1133 0 : encoder.set_nhr_tun_dport(htons(dport_));
1134 0 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1135 :
1136 0 : if (if_ksync) {
1137 0 : intf_id = if_ksync->interface_id();
1138 : }
1139 0 : encoder.set_nhr_encap_oif_id(std::vector<int32_t>(1, intf_id));
1140 0 : SetEncap(NULL,encap);
1141 0 : encoder.set_nhr_encap(encap);
1142 0 : flags |= NH_FLAG_TUNNEL_UDP;
1143 0 : if (vrf_id_ != agent->fabric_vrf()->vrf_id()) {
1144 0 : flags |= NH_FLAG_TUNNEL_SIP_COPY;
1145 : }
1146 0 : break;
1147 :
1148 3 : case NextHop::L2_RECEIVE:
1149 3 : encoder.set_nhr_type(NH_L2_RCV);
1150 3 : break;
1151 :
1152 3 : case NextHop::DISCARD:
1153 3 : encoder.set_nhr_type(NH_DISCARD);
1154 3 : break;
1155 :
1156 6 : case NextHop::RECEIVE:
1157 6 : if (!policy_) {
1158 3 : flags |= NH_FLAG_RELAXED_POLICY;
1159 : }
1160 6 : intf_id = if_ksync->interface_id();
1161 6 : encoder.set_nhr_encap_oif_id(std::vector<int32_t>(1, intf_id));
1162 6 : encoder.set_nhr_type(NH_RCV);
1163 6 : break;
1164 :
1165 3 : case NextHop::RESOLVE:
1166 3 : if (policy_) {
1167 : //Policy bit is used in agent to copy over the
1168 : //field to ARP nexthop that gets created from
1169 : //resolve NH in case of gateway interface,
1170 : //but the same is not needed in vrouter.
1171 : //If policy bit is enabled then first packet
1172 : //resulting flow with key NH of resolve NH
1173 : //followed by next packet with ARP NH as key
1174 : //resulting in flow drops
1175 0 : flags &= ~NH_FLAG_POLICY_ENABLED;
1176 : }
1177 3 : encoder.set_nhr_type(NH_RESOLVE);
1178 3 : break;
1179 :
1180 23 : case NextHop::VRF:
1181 23 : encoder.set_nhr_type(NH_VXLAN_VRF);
1182 23 : if (bridge_nh_ == true) {
1183 23 : encoder.set_nhr_family(AF_BRIDGE);
1184 : }
1185 23 : if (flood_unknown_unicast_) {
1186 0 : flags |= NH_FLAG_UNKNOWN_UC_FLOOD;
1187 : }
1188 23 : break;
1189 :
1190 0 : case NextHop::PBB: {
1191 0 : encoder.set_nhr_family(AF_BRIDGE);
1192 0 : encoder.set_nhr_type(NH_TUNNEL);
1193 0 : flags |= (NH_FLAG_TUNNEL_PBB | NH_FLAG_INDIRECT);
1194 0 : std::vector<int8_t> bmac;
1195 0 : for (size_t i = 0 ; i < dmac_.size(); i++) {
1196 0 : bmac.push_back(dmac_[i]);
1197 : }
1198 0 : encoder.set_nhr_pbb_mac(bmac);
1199 0 : if (pbb_child_nh_.get()) {
1200 0 : std::vector<int> sub_nh_list;
1201 : NHKSyncEntry *child_nh =
1202 0 : static_cast<NHKSyncEntry *>(pbb_child_nh_.get());
1203 0 : sub_nh_list.push_back(child_nh->nh_id());
1204 0 : encoder.set_nhr_nh_list(sub_nh_list);
1205 :
1206 0 : std::vector<int> sub_label_list;
1207 0 : sub_label_list.push_back(pbb_label_);
1208 0 : encoder.set_nhr_label_list(sub_label_list);
1209 0 : }
1210 : /*
1211 : * This is temp fix to handle CEM-25471
1212 : * Currently, vRouter doesn't differentiate PBB and MPLSoGRE/MPLSoUDP
1213 : * correctly and it uses encap_oif_id for PBB also which is not needed
1214 : * So, sending encap_oif_id as ZERO here in case of PBB so that vRouter
1215 : * can work in same way as it was working earlier.
1216 : */
1217 0 : encoder.set_nhr_encap_oif_id(std::vector<int32_t>(1, 0));
1218 0 : break;
1219 0 : }
1220 :
1221 186 : case NextHop::COMPOSITE: {
1222 186 : std::vector<int> sub_nh_id;
1223 186 : std::vector<int> sub_label_list;
1224 186 : std::vector<int> sub_flag_list;
1225 186 : encoder.set_nhr_type(NH_COMPOSITE);
1226 186 : assert(sip_.is_v4());
1227 186 : assert(dip_.is_v4());
1228 : /* TODO encoding */
1229 186 : encoder.set_nhr_tun_sip(htonl(sip_.to_v4().to_ulong()));
1230 186 : encoder.set_nhr_tun_dip(htonl(dip_.to_v4().to_ulong()));
1231 186 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1232 186 : encoder.set_nhr_ecmp_config_hash(SetEcmpFieldsToUse());
1233 : /* Proto encode in Network byte order */
1234 186 : switch (comp_type_) {
1235 77 : case Composite::L2INTERFACE: {
1236 77 : flags |= NH_FLAG_COMPOSITE_ENCAP;
1237 77 : encoder.set_nhr_family(AF_BRIDGE);
1238 77 : break;
1239 : }
1240 0 : case Composite::L3INTERFACE: {
1241 0 : flags |= NH_FLAG_COMPOSITE_ENCAP;
1242 0 : break;
1243 : }
1244 4 : case Composite::EVPN: {
1245 4 : flags |= NH_FLAG_COMPOSITE_EVPN;
1246 4 : break;
1247 : }
1248 0 : case Composite::TOR: {
1249 0 : flags |= NH_FLAG_COMPOSITE_TOR;
1250 0 : break;
1251 : }
1252 2 : case Composite::FABRIC: {
1253 2 : encoder.set_nhr_family(AF_BRIDGE);
1254 2 : flags |= NH_FLAG_COMPOSITE_FABRIC;
1255 2 : break;
1256 : }
1257 0 : case Composite::L3FABRIC: {
1258 0 : flags |= NH_FLAG_COMPOSITE_FABRIC;
1259 0 : break;
1260 : }
1261 101 : case Composite::L2COMP: {
1262 101 : encoder.set_nhr_family(AF_BRIDGE);
1263 101 : flags |= NH_FLAG_MCAST;
1264 101 : if (validate_mcast_src_) {
1265 101 : flags |= NH_FLAG_VALIDATE_MCAST_SRC;
1266 : }
1267 101 : break;
1268 : }
1269 0 : case Composite::L3COMP: {
1270 0 : flags |= NH_FLAG_MCAST;
1271 0 : if (validate_mcast_src_) {
1272 0 : flags |= NH_FLAG_VALIDATE_MCAST_SRC;
1273 : }
1274 0 : break;
1275 : }
1276 0 : case Composite::MULTIPROTO: {
1277 0 : encoder.set_nhr_family(AF_UNSPEC);
1278 0 : break;
1279 : }
1280 2 : case Composite::ECMP:
1281 : case Composite::LOCAL_ECMP: {
1282 2 : flags |= NH_FLAG_COMPOSITE_ECMP;
1283 2 : break;
1284 : }
1285 0 : case Composite::LU_ECMP: {
1286 0 : flags |= NH_FLAG_COMPOSITE_ECMP;
1287 0 : flags |= NH_FLAG_COMPOSITE_LU_ECMP;
1288 0 : break;
1289 : }
1290 0 : case Composite::INVALID: {
1291 0 : assert(0);
1292 : }
1293 : }
1294 186 : if (need_pbb_tunnel_) {
1295 79 : flags |= NH_FLAG_TUNNEL_PBB;
1296 : }
1297 :
1298 186 : encoder.set_nhr_flags(flags);
1299 186 : for (KSyncComponentNHList::iterator it = component_nh_list_.begin();
1300 393 : it != component_nh_list_.end(); it++) {
1301 207 : KSyncComponentNH component_nh = *it;
1302 207 : if (component_nh.nh()) {
1303 207 : sub_nh_id.push_back(component_nh.nh()->nh_id());
1304 207 : sub_label_list.push_back(component_nh.label());
1305 : } else {
1306 0 : sub_nh_id.push_back(CompositeNH::kInvalidComponentNHIdx);
1307 0 : sub_label_list.push_back(MplsTable::kInvalidLabel);
1308 : }
1309 207 : }
1310 186 : encoder.set_nhr_nh_list(sub_nh_id);
1311 186 : encoder.set_nhr_label_list(sub_label_list);
1312 186 : break;
1313 186 : }
1314 0 : default:
1315 0 : assert(0);
1316 : }
1317 455 : encoder.set_nhr_flags(flags);
1318 455 : int error = 0;
1319 455 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
1320 455 : assert(error == 0);
1321 455 : assert(encode_len <= buf_len);
1322 455 : return encode_len;
1323 878 : }
1324 :
1325 878 : void NHKSyncEntry::FillObjectLog(sandesh_op::type op, KSyncNhInfo &info)
1326 : const {
1327 878 : info.set_index(nh_id());
1328 :
1329 878 : if (op == sandesh_op::ADD) {
1330 455 : info.set_operation("ADD/CHANGE");
1331 : } else {
1332 423 : info.set_operation("DELETE");
1333 : }
1334 :
1335 878 : switch(type_) {
1336 6 : case NextHop::L2_RECEIVE: {
1337 6 : info.set_type("L2-RECEIVE");
1338 6 : break;
1339 : }
1340 6 : case NextHop::DISCARD: {
1341 6 : info.set_type("DISCARD");
1342 6 : break;
1343 : }
1344 :
1345 12 : case NextHop::RECEIVE: {
1346 12 : info.set_type("RECEIVE");
1347 12 : break;
1348 : }
1349 :
1350 6 : case NextHop::RESOLVE: {
1351 6 : info.set_type("RESOLVE");
1352 6 : break;
1353 : }
1354 :
1355 6 : case NextHop::ARP: {
1356 6 : info.set_type("ARP");
1357 : //Fill dmac and smac???
1358 6 : break;
1359 : }
1360 :
1361 0 : case NextHop::NDP: {
1362 0 : info.set_type("NDP");
1363 : //Fill dmac and smac???
1364 0 : break;
1365 : }
1366 :
1367 46 : case NextHop::VRF: {
1368 46 : info.set_type("VRF");
1369 46 : info.set_vrf(vrf_id_);
1370 46 : break;
1371 : }
1372 :
1373 400 : case NextHop::INTERFACE: {
1374 400 : info.set_type("INTERFACE");
1375 400 : break;
1376 : }
1377 :
1378 28 : case NextHop::TUNNEL: {
1379 28 : info.set_type("TUNNEL");
1380 28 : info.set_sip(sip_.to_string());
1381 28 : info.set_dip(dip_.to_string());
1382 28 : info.set_crypt_path_available(crypt_);
1383 :
1384 28 : if (crypt_interface()) {
1385 0 : info.set_crypt_intf_name(crypt_interface()->interface_name());
1386 0 : info.set_crypt_out_if_index(crypt_interface()->interface_id());
1387 : } else {
1388 28 : info.set_crypt_intf_name("NULL");
1389 28 : info.set_crypt_out_if_index(kInvalidIndex);
1390 : }
1391 28 : info.set_rewrite_dmac(rewrite_dmac_.ToString());
1392 28 : break;
1393 : }
1394 :
1395 0 : case NextHop::MIRROR: {
1396 0 : info.set_type("MIRROR");
1397 0 : info.set_vrf(vrf_id_);
1398 0 : info.set_sip(sip_.to_string());
1399 0 : info.set_dip(dip_.to_string());
1400 0 : info.set_sport(sport_);
1401 0 : info.set_dport(dport_);
1402 0 : break;
1403 : }
1404 :
1405 0 : case NextHop::VLAN: {
1406 0 : info.set_type("VLAN");
1407 0 : info.set_vlan_tag(vlan_tag_);
1408 0 : break;
1409 : }
1410 368 : case NextHop::COMPOSITE: {
1411 368 : info.set_type("Composite");
1412 368 : info.set_sub_type(comp_type_);
1413 368 : info.set_dip(dip_.to_string());
1414 368 : info.set_vrf(vrf_id_);
1415 368 : std::vector<KSyncComponentNHLog> sub_nh_list;
1416 368 : for (KSyncComponentNHList::const_iterator it =
1417 368 : component_nh_list_.begin();
1418 776 : it != component_nh_list_.end(); it++) {
1419 408 : KSyncComponentNH component_nh = *it;
1420 408 : if (component_nh.nh()) {
1421 408 : KSyncComponentNHLog sub_nh;
1422 408 : sub_nh.set_nh_idx(component_nh.nh()->nh_id());
1423 408 : sub_nh.set_label(component_nh.label());
1424 408 : sub_nh_list.push_back(sub_nh);
1425 408 : }
1426 408 : }
1427 368 : info.set_sub_nh_list(sub_nh_list);
1428 368 : break;
1429 368 : }
1430 0 : default: {
1431 0 : return;
1432 : }
1433 : }
1434 :
1435 878 : info.set_policy(policy_);
1436 878 : info.set_valid(valid_);
1437 878 : if (interface()) {
1438 418 : info.set_intf_name(interface()->interface_name());
1439 418 : info.set_out_if_index(interface()->interface_id());
1440 : } else {
1441 460 : info.set_intf_name("NULL");
1442 460 : info.set_out_if_index(kInvalidIndex);
1443 : }
1444 : }
1445 :
1446 423 : int NHKSyncEntry::AddMsg(char *buf, int buf_len) {
1447 423 : KSyncNhInfo info;
1448 423 : FillObjectLog(sandesh_op::ADD, info);
1449 423 : KSYNC_TRACE(NH, GetObject(), info);
1450 :
1451 846 : return Encode(sandesh_op::ADD, buf, buf_len);
1452 423 : }
1453 :
1454 32 : int NHKSyncEntry::ChangeMsg(char *buf, int buf_len){
1455 32 : KSyncNhInfo info;
1456 32 : FillObjectLog(sandesh_op::ADD, info);
1457 32 : KSYNC_TRACE(NH, GetObject(), info);
1458 :
1459 64 : return Encode(sandesh_op::ADD, buf, buf_len);
1460 32 : }
1461 :
1462 423 : int NHKSyncEntry::DeleteMsg(char *buf, int buf_len) {
1463 423 : KSyncNhInfo info;
1464 423 : FillObjectLog(sandesh_op::DEL, info);
1465 423 : KSYNC_TRACE(NH, GetObject(), info);
1466 :
1467 846 : return Encode(sandesh_op::DEL, buf, buf_len);
1468 423 : }
1469 :
1470 674 : KSyncEntry *NHKSyncEntry::UnresolvedReference() {
1471 674 : KSyncEntry *entry = NULL;
1472 674 : InterfaceKSyncEntry *if_ksync = interface();
1473 :
1474 674 : if (valid_ == false) {
1475 : //Invalid nexthop has no reference dependency
1476 17 : return NULL;
1477 : }
1478 :
1479 657 : switch (type_) {
1480 0 : case NextHop::ARP: {
1481 0 : assert(if_ksync);
1482 0 : if (!if_ksync->IsResolvedAndInSync()) {
1483 0 : entry = if_ksync;
1484 : }
1485 0 : break;
1486 : }
1487 :
1488 0 : case NextHop::NDP: {
1489 0 : assert(if_ksync);
1490 0 : if (!if_ksync->IsResolvedAndInSync()) {
1491 0 : entry = if_ksync;
1492 : }
1493 0 : break;
1494 : }
1495 :
1496 270 : case NextHop::VLAN:
1497 : case NextHop::INTERFACE: {
1498 270 : assert(if_ksync);
1499 270 : if (!if_ksync->IsResolvedAndInSync()) {
1500 56 : entry = if_ksync;
1501 : }
1502 270 : break;
1503 : }
1504 :
1505 3 : case NextHop::L2_RECEIVE: {
1506 3 : assert(if_ksync == NULL);
1507 3 : break;
1508 : }
1509 :
1510 3 : case NextHop::DISCARD: {
1511 3 : assert(if_ksync == NULL);
1512 3 : break;
1513 : }
1514 :
1515 0 : case NextHop::TUNNEL: {
1516 0 : if (crypt_path_available_) {
1517 0 : InterfaceKSyncEntry *crypt_if_ksync = crypt_interface();
1518 0 : assert(crypt_if_ksync);
1519 0 : if (!crypt_if_ksync->IsResolvedAndInSync()) {
1520 0 : entry = crypt_if_ksync;
1521 : }
1522 : }
1523 0 : break;
1524 : }
1525 :
1526 0 : case NextHop::MIRROR: {
1527 0 : break;
1528 : }
1529 :
1530 18 : case NextHop::RECEIVE: {
1531 18 : assert(if_ksync);
1532 18 : if (!if_ksync->IsResolvedAndInSync()) {
1533 12 : entry = if_ksync;
1534 : }
1535 18 : break;
1536 : }
1537 :
1538 23 : case NextHop::VRF: {
1539 23 : break;
1540 : }
1541 :
1542 3 : case NextHop::RESOLVE: {
1543 3 : break;
1544 : }
1545 :
1546 0 : case NextHop::PBB: {
1547 0 : if (pbb_child_nh_ && !pbb_child_nh_->IsResolvedAndInSync()) {
1548 0 : entry = pbb_child_nh_.get();
1549 : }
1550 0 : break;
1551 : }
1552 :
1553 337 : case NextHop::COMPOSITE: {
1554 337 : for (KSyncComponentNHList::const_iterator it =
1555 337 : component_nh_list_.begin();
1556 563 : it != component_nh_list_.end(); it++) {
1557 377 : KSyncComponentNH component_nh = *it;
1558 377 : if (component_nh.nh() && !(component_nh.nh()->IsResolvedAndInSync())) {
1559 151 : entry = component_nh.nh();
1560 151 : break;
1561 : }
1562 377 : }
1563 337 : break;
1564 : }
1565 :
1566 0 : default:
1567 0 : assert(0);
1568 : break;
1569 : }
1570 657 : return entry;
1571 : }
1572 :
1573 231 : static bool NeedRewrite(NHKSyncEntry *entry, InterfaceKSyncEntry *if_ksync) {
1574 :
1575 : // If interface has RAW-IP encapsulation, it doesnt need any rewrite
1576 : // information
1577 231 : if (if_ksync && if_ksync->encap_type() == PhysicalInterface::RAW_IP) {
1578 0 : return false;
1579 : }
1580 :
1581 : // For bridge nexthops, only INTERFACE nexthop has rewrite NH
1582 231 : if (entry->is_bridge() == true) {
1583 90 : if (entry->type() == NextHop::INTERFACE)
1584 90 : return true;
1585 0 : return false;
1586 : }
1587 :
1588 141 : return true;
1589 : }
1590 :
1591 231 : void NHKSyncEntry::SetEncap(InterfaceKSyncEntry *if_ksync,
1592 : std::vector<int8_t> &encap,
1593 : const int32_t index) {
1594 :
1595 231 : if (NeedRewrite(this, if_ksync) == false)
1596 0 : return;
1597 :
1598 231 : const MacAddress *smac = &MacAddress::ZeroMac();
1599 : /* DMAC encode */
1600 231 : if (type_ == NextHop::TUNNEL && index != -1) {
1601 0 : for (size_t i = 0; i < dmac_list_[index].size(); i++) {
1602 0 : encap.push_back(dmac_list_[index][i]);
1603 : }
1604 0 : } else {
1605 1617 : for (size_t i = 0 ; i < dmac_.size(); i++) {
1606 1386 : encap.push_back(dmac_[i]);
1607 : }
1608 : }
1609 : /* SMAC encode */
1610 231 : if (type_ == NextHop::VLAN) {
1611 0 : smac = &smac_;
1612 231 : } else if ((type_ == NextHop::INTERFACE || type_ == NextHop::ARP ||
1613 231 : type_ == NextHop::NDP) && if_ksync) {
1614 214 : smac = &if_ksync->mac();
1615 :
1616 : } else {
1617 17 : Agent *agent = ksync_obj_->ksync()->agent();
1618 17 : smac = &agent->vhost_interface()->mac();
1619 : }
1620 1617 : for (size_t i = 0 ; i < smac->size(); i++) {
1621 1386 : encap.push_back((*smac)[i]);
1622 : }
1623 :
1624 : // Add 802.1q header if
1625 : // - Nexthop is of type VLAN
1626 : // - Nexthop is of type INTERFACE and VLAN configured for it
1627 231 : if (type_ == NextHop::VLAN ||
1628 231 : (type_ == NextHop::INTERFACE &&
1629 214 : vlan_tag_ != VmInterface::kInvalidVlanId)) {
1630 0 : encap.push_back(0x81);
1631 0 : encap.push_back(0x00);
1632 0 : encap.push_back((vlan_tag_ & 0xFF00) >> 8);
1633 0 : encap.push_back(vlan_tag_ & 0xFF);
1634 : }
1635 : /* Proto encode in Network byte order */
1636 231 : encap.push_back(0x08);
1637 231 : encap.push_back(0x00);
1638 : }
1639 :
1640 186 : uint8_t NHKSyncEntry::SetEcmpFieldsToUse() {
1641 186 : uint8_t ecmp_hash_fields_in_use = VR_FLOW_KEY_NONE;
1642 186 : uint8_t fields_in_byte = ecmp_hash_fieds_.HashFieldsToUse();
1643 186 : if (fields_in_byte & 1 << EcmpLoadBalance::SOURCE_IP) {
1644 186 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_SRC_IP;
1645 : }
1646 186 : if (fields_in_byte & 1 << EcmpLoadBalance::DESTINATION_IP) {
1647 186 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_DST_IP;
1648 : }
1649 186 : if (fields_in_byte & 1 << EcmpLoadBalance::IP_PROTOCOL) {
1650 186 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_PROTO;
1651 : }
1652 186 : if (fields_in_byte & 1 << EcmpLoadBalance::SOURCE_PORT) {
1653 186 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_SRC_PORT;
1654 : }
1655 186 : if (fields_in_byte & 1 << EcmpLoadBalance::DESTINATION_PORT) {
1656 186 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_DST_PORT;
1657 : }
1658 :
1659 186 : return ecmp_hash_fields_in_use;
1660 :
1661 : }
1662 :
1663 3 : NHKSyncObject::NHKSyncObject(KSync *ksync) :
1664 3 : KSyncDBObject("KSync Nexthop"), ksync_(ksync) {
1665 3 : }
1666 :
1667 6 : NHKSyncObject::~NHKSyncObject() {
1668 6 : }
1669 :
1670 3 : void NHKSyncObject::RegisterDBClients() {
1671 3 : RegisterDb(ksync_->agent()->nexthop_table());
1672 3 : }
1673 :
1674 423 : KSyncEntry *NHKSyncObject::Alloc(const KSyncEntry *entry, uint32_t index) {
1675 423 : const NHKSyncEntry *nh = static_cast<const NHKSyncEntry *>(entry);
1676 423 : NHKSyncEntry *ksync = new NHKSyncEntry(this, nh, index);
1677 423 : return static_cast<KSyncEntry *>(ksync);
1678 : }
1679 :
1680 423 : KSyncEntry *NHKSyncObject::DBToKSyncEntry(const DBEntry *e) {
1681 423 : const NextHop *nh = static_cast<const NextHop *>(e);
1682 423 : NHKSyncEntry *key = new NHKSyncEntry(this, nh);
1683 423 : return static_cast<KSyncEntry *>(key);
1684 : }
1685 :
1686 878 : void vr_nexthop_req::Process(SandeshContext *context) {
1687 878 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
1688 878 : ioc->NHMsgHandler(this);
1689 878 : }
1690 :
1691 0 : void NHKSyncEntry::SetKSyncNhListSandeshData(KSyncNhListSandeshData *data) const {
1692 0 : data->set_vrf_id(vrf_id_);
1693 0 : data->set_label(label_);
1694 0 : if (valid_) {
1695 0 : data->set_valid("Enable");
1696 : } else {
1697 0 : data->set_valid("Disable");
1698 : }
1699 :
1700 0 : if (policy_) {
1701 0 : data->set_policy("Enable");
1702 : } else {
1703 0 : data->set_policy("Disable");
1704 : }
1705 :
1706 0 : if (is_mcast_nh_) {
1707 0 : data->set_is_mcast_nh("True");
1708 : } else {
1709 0 : data->set_is_mcast_nh("False");
1710 : }
1711 :
1712 0 : if (defer_) {
1713 0 : data->set_defer("Enable");
1714 : } else {
1715 0 : data->set_defer("Disable");
1716 : }
1717 :
1718 0 : data->set_vlan_tag(vlan_tag_);
1719 :
1720 0 : if (is_local_ecmp_nh_) {
1721 0 : data->set_is_local_ecmp_nh("True");
1722 : } else {
1723 0 : data->set_is_local_ecmp_nh("False");
1724 : }
1725 :
1726 0 : if (is_bridge_) {
1727 0 : data->set_is_bridge("True");
1728 : } else {
1729 0 : data->set_is_bridge("False");
1730 : }
1731 :
1732 0 : if (bridge_nh_) {
1733 0 : data->set_bridge_nh("Enable");
1734 : } else {
1735 0 : data->set_bridge_nh("Disable");
1736 : }
1737 :
1738 0 : if (flood_unknown_unicast_) {
1739 0 : data->set_flood_unknown_unicast("Enable");
1740 : } else {
1741 0 : data->set_flood_unknown_unicast("Disable");
1742 : }
1743 :
1744 0 : data->set_nh_id(nh_id_);
1745 0 : data->set_isid(isid_);
1746 0 : return;
1747 : }
1748 :
1749 0 : bool NHKSyncEntry::KSyncEntrySandesh(Sandesh *sresp) {
1750 0 : KSyncNhListResp *resp = static_cast<KSyncNhListResp *> (sresp);
1751 :
1752 0 : KSyncNhListSandeshData data;
1753 0 : SetKSyncNhListSandeshData(&data);
1754 : std::vector<KSyncNhListSandeshData> &list =
1755 0 : const_cast<std::vector<KSyncNhListSandeshData>&>(resp->get_KSyncNhList_list());
1756 0 : list.push_back(data);
1757 :
1758 0 : return true;
1759 0 : }
1760 :
1761 0 : void KSyncNhListReq::HandleRequest() const {
1762 0 : AgentKsyncSandeshPtr sand(new AgentKsyncNhListSandesh(context()));
1763 :
1764 0 : sand->DoKsyncSandesh(sand);
1765 :
1766 0 : }
|