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 160 : NHKSyncEntry::NHKSyncEntry(NHKSyncObject *obj, const NHKSyncEntry *entry,
34 160 : uint32_t index) :
35 160 : KSyncNetlinkDBEntry(index), ksync_obj_(obj), type_(entry->type_),
36 160 : vrf_id_(entry->vrf_id_), label_(entry->label_),
37 160 : interface_(entry->interface_), sip_(entry->sip_), dip_(entry->dip_),
38 160 : sport_(entry->sport_), dport_(entry->dport_), smac_(entry->smac_),
39 160 : dmac_(entry->dmac_), rewrite_dmac_(entry->rewrite_dmac_),
40 160 : valid_(entry->valid_), policy_(entry->policy_),
41 160 : is_mcast_nh_(entry->is_mcast_nh_),
42 160 : defer_(entry->defer_), component_nh_list_(entry->component_nh_list_),
43 160 : nh_(entry->nh_), vlan_tag_(entry->vlan_tag_),
44 160 : is_local_ecmp_nh_(entry->is_local_ecmp_nh_),
45 160 : is_bridge_(entry->is_bridge_),
46 160 : is_vxlan_routing_(entry->is_vxlan_routing_),
47 160 : comp_type_(entry->comp_type_),
48 160 : validate_mcast_src_(entry->validate_mcast_src_),
49 160 : tunnel_type_(entry->tunnel_type_), prefix_len_(entry->prefix_len_),
50 160 : nh_id_(entry->nh_id()),
51 160 : component_nh_key_list_(entry->component_nh_key_list_),
52 160 : bridge_nh_(entry->bridge_nh_),
53 160 : flood_unknown_unicast_(entry->flood_unknown_unicast_),
54 160 : ecmp_hash_fieds_(entry->ecmp_hash_fieds_.HashFieldsToUse()),
55 160 : pbb_child_nh_(entry->pbb_child_nh_), isid_(entry->isid_),
56 160 : pbb_label_(entry->pbb_label_), learning_enabled_(entry->learning_enabled_),
57 160 : need_pbb_tunnel_(entry->need_pbb_tunnel_), etree_leaf_(entry->etree_leaf_),
58 160 : layer2_control_word_(entry->layer2_control_word_),
59 160 : crypt_(entry->crypt_), crypt_path_available_(entry->crypt_path_available_),
60 160 : crypt_interface_(entry->crypt_interface_),
61 160 : transport_tunnel_type_(entry->transport_tunnel_type_),
62 160 : interface_list_(entry->interface_list_),
63 160 : encap_valid_list_(entry->encap_valid_list_),
64 320 : dmac_list_(entry->dmac_list_) {
65 160 : }
66 :
67 1087 : NHKSyncEntry::NHKSyncEntry(NHKSyncObject *obj, const NextHop *nh) :
68 2174 : KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj), type_(nh->GetType()),
69 3261 : vrf_id_(0), interface_(NULL), dmac_(), valid_(nh->IsValid()),
70 1087 : policy_(nh->PolicyEnabled()), is_mcast_nh_(false), nh_(nh),
71 1087 : vlan_tag_(VmInterface::kInvalidVlanId), is_bridge_(false),
72 1087 : is_vxlan_routing_(false),
73 1087 : tunnel_type_(TunnelType::INVALID), prefix_len_(32), nh_id_(nh->id()),
74 1087 : bridge_nh_(false), flood_unknown_unicast_(false),
75 1087 : learning_enabled_(nh->learning_enabled()), need_pbb_tunnel_(false),
76 1087 : etree_leaf_ (false), layer2_control_word_(false),
77 1087 : crypt_(false), crypt_path_available_(false), crypt_interface_(NULL),
78 6522 : interface_list_(), encap_valid_list_(), dmac_list_() {
79 :
80 1087 : switch (type_) {
81 31 : case NextHop::ARP: {
82 31 : const ArpNH *arp = static_cast<const ArpNH *>(nh);
83 31 : vrf_id_ = arp->vrf_id();
84 31 : sip_ = *(arp->GetIp());
85 31 : 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 669 : case NextHop::INTERFACE: {
96 : InterfaceKSyncObject *interface_object =
97 669 : ksync_obj_->ksync()->interface_ksync_obj();
98 669 : const InterfaceNH *if_nh = static_cast<const InterfaceNH *>(nh);
99 669 : InterfaceKSyncEntry if_ksync(interface_object, if_nh->GetInterface());
100 669 : interface_ = interface_object->GetReference(&if_ksync);
101 669 : assert(interface_);
102 669 : is_mcast_nh_ = if_nh->is_multicastNH();
103 669 : is_bridge_ = if_nh->IsBridge();
104 669 : is_vxlan_routing_ = if_nh->IsVxlanRouting();
105 669 : const VrfEntry * vrf = if_nh->GetVrf();
106 669 : vrf_id_ = (vrf != NULL) ? vrf->vrf_id() : VrfEntry::kInvalidIndex;
107 669 : dmac_ = if_nh->GetDMac();
108 : // VmInterface can potentially have vlan-tags. Get tag in such case
109 669 : if (if_nh->GetInterface()->type() == Interface::VM_INTERFACE) {
110 600 : vlan_tag_ = (static_cast<const VmInterface *>
111 600 : (if_nh->GetInterface()))->tx_vlan_id();
112 : }
113 669 : break;
114 669 : }
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 33 : case NextHop::TUNNEL: {
129 33 : const TunnelNH *tunnel = static_cast<const TunnelNH *>(nh);
130 33 : vrf_id_ = tunnel->vrf_id();
131 33 : sip_ = *(tunnel->GetSip());
132 33 : dip_ = *(tunnel->GetDip());
133 33 : tunnel_type_ = tunnel->GetTunnelType();
134 33 : crypt_ = tunnel->GetCrypt();
135 33 : crypt_path_available_ = tunnel->GetCryptTunnelAvailable();
136 :
137 33 : 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 33 : rewrite_dmac_ = tunnel->rewrite_dmac();
144 33 : 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 33 : break;
152 : }
153 :
154 35 : case NextHop::DISCARD: {
155 35 : break;
156 : }
157 :
158 58 : case NextHop::L2_RECEIVE: {
159 58 : break;
160 : }
161 :
162 12 : case NextHop::RESOLVE: {
163 : InterfaceKSyncObject *interface_object =
164 12 : ksync_obj_->ksync()->interface_ksync_obj();
165 12 : const ResolveNH *rsl_nh = static_cast<const ResolveNH *>(nh);
166 12 : InterfaceKSyncEntry if_ksync(interface_object, rsl_nh->get_interface());
167 12 : interface_ = interface_object->GetReference(&if_ksync);
168 12 : vrf_id_ = rsl_nh->get_interface()->vrf_id();
169 12 : if (rsl_nh->get_interface()->type() == Interface::VM_INTERFACE) {
170 : const VmInterface *vm_intf =
171 12 : static_cast<const VmInterface *>(rsl_nh->get_interface());
172 12 : if (vm_intf->vrf()->forwarding_vrf()) {
173 12 : vrf_id_ = vm_intf->vrf()->forwarding_vrf()->vrf_id();
174 : }
175 : }
176 12 : break;
177 12 : }
178 :
179 9 : case NextHop::VRF: {
180 9 : const VrfNH *vrf_nh = static_cast<const VrfNH *>(nh);
181 9 : vrf_id_ = vrf_nh->GetVrf()->vrf_id();
182 9 : bridge_nh_ = vrf_nh->bridge_nh();
183 9 : break;
184 : }
185 :
186 35 : case NextHop::RECEIVE: {
187 : InterfaceKSyncObject *interface_object =
188 35 : ksync_obj_->ksync()->interface_ksync_obj();
189 35 : const ReceiveNH *rcv_nh = static_cast<const ReceiveNH *>(nh);
190 35 : InterfaceKSyncEntry if_ksync(interface_object, rcv_nh->GetInterface());
191 35 : interface_ = interface_object->GetReference(&if_ksync);
192 35 : vrf_id_ = rcv_nh->GetInterface()->vrf_id();
193 35 : assert(interface_);
194 35 : break;
195 35 : }
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 205 : case NextHop::COMPOSITE: {
216 205 : const CompositeNH *comp_nh = static_cast<const CompositeNH *>(nh);
217 205 : component_nh_list_.clear();
218 205 : vrf_id_ = comp_nh->vrf()->vrf_id();
219 205 : comp_type_ = comp_nh->composite_nh_type();
220 205 : validate_mcast_src_ = comp_nh->validate_mcast_src();
221 205 : ecmp_hash_fieds_ =
222 205 : const_cast<CompositeNH *>(comp_nh)->CompEcmpHashFields().HashFieldsToUse();
223 205 : component_nh_key_list_ = comp_nh->component_nh_key_list();
224 : ComponentNHList::const_iterator component_nh_it =
225 205 : comp_nh->begin();
226 514 : while (component_nh_it != comp_nh->end()) {
227 309 : const NextHop *component_nh = NULL;
228 309 : uint32_t label = 0;
229 309 : if (*component_nh_it) {
230 309 : component_nh = (*component_nh_it)->nh();
231 309 : label = (*component_nh_it)->label();
232 : }
233 309 : KSyncEntry *ksync_nh = NULL;
234 309 : if (component_nh != NULL) {
235 : NHKSyncObject *nh_object =
236 309 : ksync_obj_->ksync()->nh_ksync_obj();
237 309 : NHKSyncEntry nhksync(nh_object, component_nh);
238 309 : ksync_nh = nh_object->GetReference(&nhksync);
239 309 : }
240 309 : KSyncComponentNH ksync_component_nh(label, ksync_nh);
241 309 : component_nh_list_.push_back(ksync_component_nh);
242 309 : component_nh_it++;
243 309 : }
244 205 : break;
245 : }
246 :
247 0 : default:
248 0 : assert(0);
249 : break;
250 : }
251 1087 : }
252 :
253 1567 : NHKSyncEntry::~NHKSyncEntry() {
254 1567 : }
255 :
256 2084 : KSyncDBObject *NHKSyncEntry::GetObject() const {
257 2084 : return ksync_obj_;
258 : }
259 :
260 9216 : bool NHKSyncEntry::IsLess(const KSyncEntry &rhs) const {
261 9216 : const NHKSyncEntry &entry = static_cast<const NHKSyncEntry &>(rhs);
262 :
263 9216 : if (type_ != entry.type_) {
264 2399 : return type_ < entry.type_;
265 : }
266 :
267 6817 : if (type_ == NextHop::DISCARD) {
268 70 : return false;
269 : }
270 :
271 6747 : if (type_ == NextHop::L2_RECEIVE) {
272 116 : return false;
273 : }
274 :
275 6631 : if (type_ == NextHop::ARP || type_ == NextHop::NDP) {
276 : //Policy is ignored for ARP NH
277 62 : if (vrf_id_ != entry.vrf_id_) {
278 0 : return vrf_id_ < entry.vrf_id_;
279 : }
280 62 : return sip_ < entry.sip_;
281 : }
282 :
283 6569 : if (policy_ != entry.policy_) {
284 883 : return policy_ < entry.policy_;
285 : }
286 :
287 5686 : if (type_ == NextHop::VRF) {
288 18 : if ( vrf_id_ != entry.vrf_id_) {
289 0 : return vrf_id_ < entry.vrf_id_;
290 : }
291 18 : return bridge_nh_ < entry.bridge_nh_;
292 : }
293 :
294 5668 : if (type_ == NextHop::INTERFACE) {
295 4516 : if (is_mcast_nh_ != entry.is_mcast_nh_) {
296 568 : return is_mcast_nh_ < entry.is_mcast_nh_;
297 : }
298 3948 : if(is_bridge_ != entry.is_bridge_) {
299 989 : return is_bridge_ < entry.is_bridge_;
300 : }
301 :
302 2959 : if(is_vxlan_routing_ != entry.is_vxlan_routing_) {
303 0 : return is_vxlan_routing_ < entry.is_vxlan_routing_;
304 : }
305 :
306 2959 : if (dmac_ != entry.dmac_) {
307 1408 : return dmac_ < entry.dmac_;
308 : }
309 :
310 1551 : return interface() < entry.interface();
311 : }
312 :
313 1152 : if (type_ == NextHop::RECEIVE || type_ == NextHop::RESOLVE) {
314 94 : return interface() < entry.interface();
315 : }
316 :
317 :
318 1058 : if (type_ == NextHop::TUNNEL) {
319 121 : if (vrf_id_ != entry.vrf_id_) {
320 0 : return vrf_id_ < entry.vrf_id_;
321 : }
322 :
323 121 : if (sip_ != entry.sip_) {
324 0 : return sip_ < entry.sip_;
325 : }
326 :
327 121 : if (dip_ != entry.dip_) {
328 39 : return dip_ < entry.dip_;
329 : }
330 :
331 82 : if (crypt_ != entry.crypt_) {
332 0 : return crypt_ < entry.crypt_;
333 : }
334 :
335 82 : if (crypt_path_available_ != entry.crypt_path_available_) {
336 0 : return crypt_path_available_ < entry.crypt_path_available_;
337 : }
338 :
339 82 : if (crypt_interface() != entry.crypt_interface()) {
340 0 : return crypt_interface() < entry.crypt_interface();
341 : }
342 :
343 82 : if (rewrite_dmac_ != entry.rewrite_dmac_) {
344 0 : return rewrite_dmac_ < entry.rewrite_dmac_;
345 : }
346 82 : if (tunnel_type_.Compare(entry.tunnel_type_) == false) {
347 16 : return tunnel_type_.IsLess(entry.tunnel_type_);
348 : }
349 66 : if (tunnel_type_.GetType() == TunnelType::MPLS_OVER_MPLS) {
350 0 : return label_ < entry.label_;
351 : }
352 : }
353 :
354 1003 : 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 1003 : 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 1003 : if (type_ == NextHop::COMPOSITE) {
379 937 : if (comp_type_ != entry.comp_type_) {
380 262 : return comp_type_ < entry.comp_type_;
381 : }
382 :
383 675 : if (vrf_id_ != entry.vrf_id_) {
384 0 : return vrf_id_ < entry.vrf_id_;
385 : }
386 :
387 : ComponentNHKeyList::const_iterator it =
388 675 : component_nh_key_list_.begin();
389 : ComponentNHKeyList::const_iterator entry_it =
390 675 : entry.component_nh_key_list_.begin();
391 2396 : for (;it != component_nh_key_list_.end() &&
392 3167 : entry_it != entry.component_nh_key_list_.end(); it++, entry_it++) {
393 914 : if (*it == NULL &&
394 0 : *entry_it == NULL) {
395 0 : continue;
396 : }
397 : //One of the component NH is NULL
398 1828 : if ((*it) == NULL ||
399 914 : (*entry_it) == NULL) {
400 0 : return (*it) < (*entry_it);
401 : }
402 :
403 : //Check if the label is different
404 1828 : if ((*it)->label() !=
405 914 : (*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 914 : const NextHopKey *left_nh = (*it)->nh_key();
416 914 : const NextHopKey *right_nh = (*entry_it)->nh_key();
417 :
418 914 : if (left_nh->IsEqual(*right_nh) == false) {
419 143 : if (left_nh->GetType() != right_nh->GetType()) {
420 0 : return left_nh->GetType() < right_nh->GetType();
421 : }
422 143 : return left_nh->IsLess(*right_nh);
423 : }
424 :
425 : }
426 :
427 1028 : if (it == component_nh_key_list_.end() &&
428 1028 : entry_it == entry.component_nh_key_list_.end()) {
429 410 : return false;
430 : }
431 :
432 122 : if (it == component_nh_key_list_.end()) {
433 86 : return true;
434 : }
435 36 : return false;
436 : }
437 :
438 66 : 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 66 : return false;
448 :
449 : assert(0);
450 : }
451 :
452 3250 : std::string NHKSyncEntry::ToString() const {
453 3250 : std::stringstream s;
454 3250 : s << "NextHop Index: " << nh_id() << " Type: ";
455 3250 : switch(type_) {
456 57 : case NextHop::DISCARD: {
457 57 : s << "Discard";
458 57 : break;
459 : }
460 119 : case NextHop::L2_RECEIVE: {
461 119 : s << "L2-Receive ";
462 119 : break;
463 : }
464 82 : case NextHop::RECEIVE: {
465 82 : s << "Receive ";
466 82 : break;
467 : }
468 24 : case NextHop::RESOLVE: {
469 24 : s << "Resolve ";
470 24 : break;
471 : }
472 48 : case NextHop::ARP: {
473 48 : s << "ARP ";
474 48 : break;
475 : }
476 0 : case NextHop::NDP: {
477 0 : s << "NDP ";
478 0 : break;
479 : }
480 42 : case NextHop::VRF: {
481 42 : s << "VRF assign to ";
482 : const VrfEntry* vrf =
483 42 : ksync_obj_->ksync()->agent()->vrf_table()->
484 42 : FindVrfFromId(vrf_id_);
485 42 : if (vrf) {
486 42 : s << vrf->GetName() << " ";
487 : } else {
488 0 : s << "Invalid ";
489 : }
490 42 : break;
491 : }
492 2032 : case NextHop::INTERFACE: {
493 2032 : s << "Interface ";
494 2032 : break;
495 : }
496 107 : case NextHop::TUNNEL: {
497 107 : s << "Tunnel to ";
498 107 : s << dip_.to_string();
499 107 : s << "rewrite_dmac";
500 107 : s << rewrite_dmac_.ToString();
501 107 : 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 739 : case NextHop::COMPOSITE: {
513 739 : s << "Composite Child members: ";
514 739 : if (component_nh_list_.size() == 0) {
515 37 : s << "Empty ";
516 : }
517 739 : for (KSyncComponentNHList::const_iterator it = component_nh_list_.begin();
518 1805 : it != component_nh_list_.end(); it++) {
519 1066 : KSyncComponentNH component_nh = *it;
520 1066 : if (component_nh.nh()) {
521 1066 : s << component_nh.nh()->ToString();
522 : }
523 1066 : }
524 739 : 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 3250 : if (interface_) {
537 2138 : s << "<" << interface_->ToString() << ">";
538 : }
539 6500 : return s.str();
540 3250 : }
541 :
542 161 : bool NHKSyncEntry::Sync(DBEntry *e) {
543 161 : bool ret = false;
544 161 : const NextHop *nh = static_cast<NextHop *>(e);
545 :
546 161 : if (valid_ != nh->IsValid()) {
547 0 : valid_ = nh->IsValid();
548 0 : ret = true;
549 : }
550 :
551 161 : if (learning_enabled_ != nh->learning_enabled()) {
552 0 : learning_enabled_ = nh->learning_enabled();
553 0 : ret = true;
554 : }
555 :
556 161 : if (etree_leaf_ != nh->etree_leaf()) {
557 0 : etree_leaf_ = nh->etree_leaf();
558 0 : ret = true;
559 : }
560 :
561 161 : 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 87 : case NextHop::INTERFACE: {
615 87 : InterfaceNH *intf_nh = static_cast<InterfaceNH *>(e);
616 87 : dmac_ = intf_nh->GetDMac();
617 87 : uint16_t vlan_tag = VmInterface::kInvalidVlanId;
618 87 : if (intf_nh->GetInterface()->type() == Interface::VM_INTERFACE) {
619 75 : vlan_tag = vlan_tag_;
620 75 : vlan_tag_ = (static_cast<const VmInterface *>
621 75 : (intf_nh->GetInterface()))->tx_vlan_id();
622 75 : if (vlan_tag != vlan_tag_) {
623 0 : ret = true;
624 : }
625 : }
626 87 : 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 87 : const VrfEntry * vrf = intf_nh->GetVrf();
632 87 : uint32_t vrf_id = (vrf != NULL)? vrf->vrf_id() :VrfEntry::kInvalidIndex;
633 87 : if (vrf_id_ != vrf_id) {
634 0 : vrf_id_ = vrf_id;
635 0 : ret = true;
636 : }
637 87 : 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 9 : case NextHop::TUNNEL: {
651 9 : 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 9 : 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 9 : if (valid_ == false) {
665 9 : if (interface_ != NULL) {
666 0 : interface_ = NULL;
667 0 : dmac_.Zero();
668 0 : ret = true;
669 : }
670 9 : 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 43 : case NextHop::COMPOSITE: {
882 43 : ret = true;
883 43 : CompositeNH *comp_nh = static_cast<CompositeNH *>(e);
884 43 : component_nh_list_.clear();
885 : ComponentNHList::const_iterator component_nh_it =
886 43 : comp_nh->begin();
887 102 : while (component_nh_it != comp_nh->end()) {
888 59 : const NextHop *component_nh = NULL;
889 59 : uint32_t label = 0;
890 59 : if (*component_nh_it) {
891 59 : component_nh = (*component_nh_it)->nh();
892 59 : label = (*component_nh_it)->label();
893 : }
894 59 : KSyncEntry *ksync_nh = NULL;
895 59 : if (component_nh != NULL) {
896 : NHKSyncObject *nh_object =
897 59 : ksync_obj_->ksync()->nh_ksync_obj();
898 59 : NHKSyncEntry nhksync(nh_object, component_nh);
899 59 : ksync_nh = nh_object->GetReference(&nhksync);
900 59 : }
901 59 : KSyncComponentNH ksync_component_nh(label, ksync_nh);
902 59 : component_nh_list_.push_back(ksync_component_nh);
903 59 : component_nh_it++;
904 59 : }
905 :
906 43 : if (comp_nh->EcmpHashFieldInUse() != ecmp_hash_fieds_.HashFieldsToUse()) {
907 0 : ecmp_hash_fieds_ = comp_nh->CompEcmpHashFields().HashFieldsToUse();
908 0 : ret = true;
909 : }
910 :
911 43 : if (need_pbb_tunnel_ != comp_nh->pbb_nh()) {
912 0 : need_pbb_tunnel_ = comp_nh->pbb_nh();
913 0 : ret = true;
914 : }
915 :
916 43 : 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 43 : 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 3 : case NextHop::VRF: {
932 3 : VrfNH *vrf_nh = static_cast<VrfNH *>(e);
933 3 : vrf_id_ = vrf_nh->GetVrf()->vrf_id();
934 3 : ret = false;
935 3 : if (bridge_nh_ != vrf_nh->bridge_nh()) {
936 0 : bridge_nh_ = vrf_nh->bridge_nh();
937 0 : ret = true;
938 : }
939 :
940 3 : 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 3 : 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 3 : 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 161 : return ret;
963 : };
964 320 : int NHKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
965 320 : vr_nexthop_req encoder;
966 : int encode_len;
967 320 : uint32_t crypt_intf_id = kInvalidIndex;
968 320 : uint32_t intf_id = kInvalidIndex;
969 320 : std::vector<int8_t> encap;
970 320 : InterfaceKSyncEntry *if_ksync = NULL;
971 320 : InterfaceKSyncEntry *crypt_if_ksync = NULL;
972 320 : std::vector<KSyncEntryPtr> if_ksync_list;
973 320 : std::vector<int32_t> nhr_encap_valid_list;
974 320 : std::vector<int32_t> intf_id_list;
975 320 : Agent *agent = ksync_obj_->ksync()->agent();
976 :
977 320 : encoder.set_h_op(op);
978 320 : encoder.set_nhr_id(nh_id());
979 320 : if (op == sandesh_op::DEL) {
980 : /* For delete only NH-index is required by vrouter */
981 160 : int error = 0;
982 160 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
983 160 : assert(error == 0);
984 160 : assert(encode_len <= buf_len);
985 160 : return encode_len;
986 : }
987 160 : encoder.set_nhr_rid(0);
988 160 : encoder.set_nhr_vrf(vrf_id_);
989 160 : encoder.set_nhr_family(AF_INET);
990 160 : uint32_t flags = 0;
991 160 : if (valid_) {
992 148 : flags |= NH_FLAG_VALID;
993 : }
994 :
995 160 : if (policy_) {
996 37 : flags |= NH_FLAG_POLICY_ENABLED;
997 : }
998 :
999 160 : if (etree_leaf_ == false) {
1000 160 : flags |= NH_FLAG_ETREE_ROOT;
1001 : }
1002 :
1003 160 : if (learning_enabled_) {
1004 0 : flags |= NH_FLAG_MAC_LEARN;
1005 : }
1006 :
1007 160 : if (layer2_control_word_) {
1008 0 : flags |= NH_FLAG_L2_CONTROL_DATA;
1009 : }
1010 :
1011 160 : if (crypt_) {
1012 0 : flags |= NH_FLAG_CRYPT_TRAFFIC;
1013 : }
1014 :
1015 160 : if_ksync = interface();
1016 160 : if_ksync_list = interface_list();
1017 160 : nhr_encap_valid_list = encap_valid_list();
1018 160 : crypt_if_ksync = crypt_interface();
1019 :
1020 160 : switch (type_) {
1021 90 : case NextHop::VLAN:
1022 : case NextHop::ARP:
1023 : case NextHop::NDP:
1024 : case NextHop::INTERFACE :
1025 90 : encoder.set_nhr_type(NH_ENCAP);
1026 90 : if (if_ksync) {
1027 87 : intf_id = if_ksync->interface_id();
1028 : }
1029 90 : encoder.set_nhr_encap_oif_id(std::vector<int32_t>(1, intf_id));
1030 90 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1031 :
1032 90 : SetEncap(if_ksync, encap);
1033 90 : encoder.set_nhr_encap(encap);
1034 90 : encoder.set_nhr_tun_sip(0);
1035 90 : encoder.set_nhr_tun_dip(0);
1036 90 : if (is_vxlan_routing_) {
1037 : //Set vxlan routing flag
1038 0 : flags |= NH_FLAG_L3_VXLAN;
1039 : }
1040 90 : if (is_bridge_) {
1041 30 : encoder.set_nhr_family(AF_BRIDGE);
1042 : }
1043 90 : if (is_mcast_nh_) {
1044 15 : flags |= NH_FLAG_MCAST;
1045 : }
1046 90 : encoder.set_nhr_flags(flags);
1047 90 : break;
1048 :
1049 9 : case NextHop::TUNNEL : {
1050 9 : encoder.set_nhr_type(NH_TUNNEL);
1051 9 : encoder.set_nhr_tun_sip(htonl(sip_.to_v4().to_ulong()));
1052 9 : encoder.set_nhr_tun_dip(htonl(dip_.to_v4().to_ulong()));
1053 9 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1054 :
1055 9 : 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 9 : SetEncap(if_ksync, encap);
1069 9 : intf_id_list.push_back(0);
1070 : }
1071 9 : encoder.set_nhr_encap_oif_id(intf_id_list);
1072 9 : encoder.set_nhr_encap_valid(nhr_encap_valid_list);
1073 9 : encoder.set_nhr_crypt_traffic(crypt_);
1074 9 : encoder.set_nhr_crypt_path_available(crypt_path_available_);
1075 9 : if (crypt_if_ksync && crypt_path_available_) {
1076 0 : crypt_intf_id = crypt_if_ksync->interface_id();
1077 : }
1078 9 : encoder.set_nhr_encap_crypt_oif_id(crypt_intf_id);
1079 9 : encoder.set_nhr_encap(encap);
1080 9 : if (tunnel_type_.GetType() == TunnelType::MPLS_UDP) {
1081 0 : flags |= NH_FLAG_TUNNEL_UDP_MPLS;
1082 9 : } else if (tunnel_type_.GetType() == TunnelType::MPLS_GRE) {
1083 5 : 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 9 : std::vector<int8_t> rewrite_dmac;
1107 63 : for (size_t i = 0 ; i < rewrite_dmac_.size(); i++) {
1108 54 : rewrite_dmac.push_back(rewrite_dmac_[i]);
1109 : }
1110 9 : encoder.set_nhr_rw_dst_mac(rewrite_dmac);
1111 : //TODO remove set_nhr_pbb_mac
1112 9 : encoder.set_nhr_pbb_mac(rewrite_dmac);
1113 9 : if (rewrite_dmac_.IsZero() == false) {
1114 0 : flags |= NH_FLAG_L3_VXLAN;
1115 : }
1116 9 : break;
1117 9 : }
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 3 : case NextHop::VRF:
1181 3 : encoder.set_nhr_type(NH_VXLAN_VRF);
1182 3 : if (bridge_nh_ == true) {
1183 3 : encoder.set_nhr_family(AF_BRIDGE);
1184 : }
1185 3 : if (flood_unknown_unicast_) {
1186 0 : flags |= NH_FLAG_UNKNOWN_UC_FLOOD;
1187 : }
1188 3 : 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 43 : case NextHop::COMPOSITE: {
1222 43 : std::vector<int> sub_nh_id;
1223 43 : std::vector<int> sub_label_list;
1224 43 : std::vector<int> sub_flag_list;
1225 43 : encoder.set_nhr_type(NH_COMPOSITE);
1226 43 : assert(sip_.is_v4());
1227 43 : assert(dip_.is_v4());
1228 : /* TODO encoding */
1229 43 : encoder.set_nhr_tun_sip(htonl(sip_.to_v4().to_ulong()));
1230 43 : encoder.set_nhr_tun_dip(htonl(dip_.to_v4().to_ulong()));
1231 43 : encoder.set_nhr_encap_family(ETHERTYPE_ARP);
1232 43 : encoder.set_nhr_ecmp_config_hash(SetEcmpFieldsToUse());
1233 : /* Proto encode in Network byte order */
1234 43 : switch (comp_type_) {
1235 19 : case Composite::L2INTERFACE: {
1236 19 : flags |= NH_FLAG_COMPOSITE_ENCAP;
1237 19 : encoder.set_nhr_family(AF_BRIDGE);
1238 19 : break;
1239 : }
1240 0 : case Composite::L3INTERFACE: {
1241 0 : flags |= NH_FLAG_COMPOSITE_ENCAP;
1242 0 : break;
1243 : }
1244 0 : case Composite::EVPN: {
1245 0 : flags |= NH_FLAG_COMPOSITE_EVPN;
1246 0 : break;
1247 : }
1248 0 : case Composite::TOR: {
1249 0 : flags |= NH_FLAG_COMPOSITE_TOR;
1250 0 : break;
1251 : }
1252 0 : case Composite::FABRIC: {
1253 0 : encoder.set_nhr_family(AF_BRIDGE);
1254 0 : flags |= NH_FLAG_COMPOSITE_FABRIC;
1255 0 : break;
1256 : }
1257 0 : case Composite::L3FABRIC: {
1258 0 : flags |= NH_FLAG_COMPOSITE_FABRIC;
1259 0 : break;
1260 : }
1261 22 : case Composite::L2COMP: {
1262 22 : encoder.set_nhr_family(AF_BRIDGE);
1263 22 : flags |= NH_FLAG_MCAST;
1264 22 : if (validate_mcast_src_) {
1265 22 : flags |= NH_FLAG_VALIDATE_MCAST_SRC;
1266 : }
1267 22 : 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 43 : if (need_pbb_tunnel_) {
1295 0 : flags |= NH_FLAG_TUNNEL_PBB;
1296 : }
1297 :
1298 43 : encoder.set_nhr_flags(flags);
1299 43 : for (KSyncComponentNHList::iterator it = component_nh_list_.begin();
1300 102 : it != component_nh_list_.end(); it++) {
1301 59 : KSyncComponentNH component_nh = *it;
1302 59 : if (component_nh.nh()) {
1303 59 : sub_nh_id.push_back(component_nh.nh()->nh_id());
1304 59 : 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 59 : }
1310 43 : encoder.set_nhr_nh_list(sub_nh_id);
1311 43 : encoder.set_nhr_label_list(sub_label_list);
1312 43 : break;
1313 43 : }
1314 0 : default:
1315 0 : assert(0);
1316 : }
1317 160 : encoder.set_nhr_flags(flags);
1318 160 : int error = 0;
1319 160 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
1320 160 : assert(error == 0);
1321 160 : assert(encode_len <= buf_len);
1322 160 : return encode_len;
1323 320 : }
1324 :
1325 320 : void NHKSyncEntry::FillObjectLog(sandesh_op::type op, KSyncNhInfo &info)
1326 : const {
1327 320 : info.set_index(nh_id());
1328 :
1329 320 : if (op == sandesh_op::ADD) {
1330 160 : info.set_operation("ADD/CHANGE");
1331 : } else {
1332 160 : info.set_operation("DELETE");
1333 : }
1334 :
1335 320 : 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 6 : case NextHop::VRF: {
1368 6 : info.set_type("VRF");
1369 6 : info.set_vrf(vrf_id_);
1370 6 : break;
1371 : }
1372 :
1373 174 : case NextHop::INTERFACE: {
1374 174 : info.set_type("INTERFACE");
1375 174 : break;
1376 : }
1377 :
1378 18 : case NextHop::TUNNEL: {
1379 18 : info.set_type("TUNNEL");
1380 18 : info.set_sip(sip_.to_string());
1381 18 : info.set_dip(dip_.to_string());
1382 18 : info.set_crypt_path_available(crypt_);
1383 :
1384 18 : 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 18 : info.set_crypt_intf_name("NULL");
1389 18 : info.set_crypt_out_if_index(kInvalidIndex);
1390 : }
1391 18 : info.set_rewrite_dmac(rewrite_dmac_.ToString());
1392 18 : 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 86 : case NextHop::COMPOSITE: {
1411 86 : info.set_type("Composite");
1412 86 : info.set_sub_type(comp_type_);
1413 86 : info.set_dip(dip_.to_string());
1414 86 : info.set_vrf(vrf_id_);
1415 86 : std::vector<KSyncComponentNHLog> sub_nh_list;
1416 86 : for (KSyncComponentNHList::const_iterator it =
1417 86 : component_nh_list_.begin();
1418 204 : it != component_nh_list_.end(); it++) {
1419 118 : KSyncComponentNH component_nh = *it;
1420 118 : if (component_nh.nh()) {
1421 118 : KSyncComponentNHLog sub_nh;
1422 118 : sub_nh.set_nh_idx(component_nh.nh()->nh_id());
1423 118 : sub_nh.set_label(component_nh.label());
1424 118 : sub_nh_list.push_back(sub_nh);
1425 118 : }
1426 118 : }
1427 86 : info.set_sub_nh_list(sub_nh_list);
1428 86 : break;
1429 86 : }
1430 0 : default: {
1431 0 : return;
1432 : }
1433 : }
1434 :
1435 320 : info.set_policy(policy_);
1436 320 : info.set_valid(valid_);
1437 320 : if (interface()) {
1438 192 : info.set_intf_name(interface()->interface_name());
1439 192 : info.set_out_if_index(interface()->interface_id());
1440 : } else {
1441 128 : info.set_intf_name("NULL");
1442 128 : info.set_out_if_index(kInvalidIndex);
1443 : }
1444 : }
1445 :
1446 160 : int NHKSyncEntry::AddMsg(char *buf, int buf_len) {
1447 160 : KSyncNhInfo info;
1448 160 : FillObjectLog(sandesh_op::ADD, info);
1449 160 : KSYNC_TRACE(NH, GetObject(), info);
1450 :
1451 320 : return Encode(sandesh_op::ADD, buf, buf_len);
1452 160 : }
1453 :
1454 0 : int NHKSyncEntry::ChangeMsg(char *buf, int buf_len){
1455 0 : KSyncNhInfo info;
1456 0 : FillObjectLog(sandesh_op::ADD, info);
1457 0 : KSYNC_TRACE(NH, GetObject(), info);
1458 :
1459 0 : return Encode(sandesh_op::ADD, buf, buf_len);
1460 0 : }
1461 :
1462 160 : int NHKSyncEntry::DeleteMsg(char *buf, int buf_len) {
1463 160 : KSyncNhInfo info;
1464 160 : FillObjectLog(sandesh_op::DEL, info);
1465 160 : KSYNC_TRACE(NH, GetObject(), info);
1466 :
1467 320 : return Encode(sandesh_op::DEL, buf, buf_len);
1468 160 : }
1469 :
1470 259 : KSyncEntry *NHKSyncEntry::UnresolvedReference() {
1471 259 : KSyncEntry *entry = NULL;
1472 259 : InterfaceKSyncEntry *if_ksync = interface();
1473 :
1474 259 : if (valid_ == false) {
1475 : //Invalid nexthop has no reference dependency
1476 12 : return NULL;
1477 : }
1478 :
1479 247 : 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 140 : case NextHop::VLAN:
1497 : case NextHop::INTERFACE: {
1498 140 : assert(if_ksync);
1499 140 : if (!if_ksync->IsResolvedAndInSync()) {
1500 53 : entry = if_ksync;
1501 : }
1502 140 : 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 3 : case NextHop::VRF: {
1539 3 : 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 77 : case NextHop::COMPOSITE: {
1554 77 : for (KSyncComponentNHList::const_iterator it =
1555 77 : component_nh_list_.begin();
1556 142 : it != component_nh_list_.end(); it++) {
1557 99 : KSyncComponentNH component_nh = *it;
1558 99 : if (component_nh.nh() && !(component_nh.nh()->IsResolvedAndInSync())) {
1559 34 : entry = component_nh.nh();
1560 34 : break;
1561 : }
1562 99 : }
1563 77 : break;
1564 : }
1565 :
1566 0 : default:
1567 0 : assert(0);
1568 : break;
1569 : }
1570 247 : return entry;
1571 : }
1572 :
1573 99 : static bool NeedRewrite(NHKSyncEntry *entry, InterfaceKSyncEntry *if_ksync) {
1574 :
1575 : // If interface has RAW-IP encapsulation, it doesnt need any rewrite
1576 : // information
1577 99 : 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 99 : if (entry->is_bridge() == true) {
1583 30 : if (entry->type() == NextHop::INTERFACE)
1584 30 : return true;
1585 0 : return false;
1586 : }
1587 :
1588 69 : return true;
1589 : }
1590 :
1591 99 : void NHKSyncEntry::SetEncap(InterfaceKSyncEntry *if_ksync,
1592 : std::vector<int8_t> &encap,
1593 : const int32_t index) {
1594 :
1595 99 : if (NeedRewrite(this, if_ksync) == false)
1596 0 : return;
1597 :
1598 99 : const MacAddress *smac = &MacAddress::ZeroMac();
1599 : /* DMAC encode */
1600 99 : 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 693 : for (size_t i = 0 ; i < dmac_.size(); i++) {
1606 594 : encap.push_back(dmac_[i]);
1607 : }
1608 : }
1609 : /* SMAC encode */
1610 99 : if (type_ == NextHop::VLAN) {
1611 0 : smac = &smac_;
1612 99 : } else if ((type_ == NextHop::INTERFACE || type_ == NextHop::ARP ||
1613 99 : type_ == NextHop::NDP) && if_ksync) {
1614 87 : smac = &if_ksync->mac();
1615 :
1616 : } else {
1617 12 : Agent *agent = ksync_obj_->ksync()->agent();
1618 12 : smac = &agent->vhost_interface()->mac();
1619 : }
1620 693 : for (size_t i = 0 ; i < smac->size(); i++) {
1621 594 : 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 99 : if (type_ == NextHop::VLAN ||
1628 99 : (type_ == NextHop::INTERFACE &&
1629 87 : 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 99 : encap.push_back(0x08);
1637 99 : encap.push_back(0x00);
1638 : }
1639 :
1640 43 : uint8_t NHKSyncEntry::SetEcmpFieldsToUse() {
1641 43 : uint8_t ecmp_hash_fields_in_use = VR_FLOW_KEY_NONE;
1642 43 : uint8_t fields_in_byte = ecmp_hash_fieds_.HashFieldsToUse();
1643 43 : if (fields_in_byte & 1 << EcmpLoadBalance::SOURCE_IP) {
1644 43 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_SRC_IP;
1645 : }
1646 43 : if (fields_in_byte & 1 << EcmpLoadBalance::DESTINATION_IP) {
1647 43 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_DST_IP;
1648 : }
1649 43 : if (fields_in_byte & 1 << EcmpLoadBalance::IP_PROTOCOL) {
1650 43 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_PROTO;
1651 : }
1652 43 : if (fields_in_byte & 1 << EcmpLoadBalance::SOURCE_PORT) {
1653 43 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_SRC_PORT;
1654 : }
1655 43 : if (fields_in_byte & 1 << EcmpLoadBalance::DESTINATION_PORT) {
1656 43 : ecmp_hash_fields_in_use |= VR_FLOW_KEY_DST_PORT;
1657 : }
1658 :
1659 43 : 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 160 : KSyncEntry *NHKSyncObject::Alloc(const KSyncEntry *entry, uint32_t index) {
1675 160 : const NHKSyncEntry *nh = static_cast<const NHKSyncEntry *>(entry);
1676 160 : NHKSyncEntry *ksync = new NHKSyncEntry(this, nh, index);
1677 160 : return static_cast<KSyncEntry *>(ksync);
1678 : }
1679 :
1680 160 : KSyncEntry *NHKSyncObject::DBToKSyncEntry(const DBEntry *e) {
1681 160 : const NextHop *nh = static_cast<const NextHop *>(e);
1682 160 : NHKSyncEntry *key = new NHKSyncEntry(this, nh);
1683 160 : return static_cast<KSyncEntry *>(key);
1684 : }
1685 :
1686 320 : void vr_nexthop_req::Process(SandeshContext *context) {
1687 320 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
1688 320 : ioc->NHMsgHandler(this);
1689 320 : }
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 : }
|