Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <stdio.h>
6 : #include <string.h>
7 :
8 : #include <net/if.h>
9 :
10 : #include <boost/asio.hpp>
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 : #include <vrouter/ksync/ksync_agent_sandesh.h>
20 : #include <init/agent_param.h>
21 : #include "vrouter/ksync/agent_ksync_types.h"
22 : #include "vr_types.h"
23 : #include "base/logging.h"
24 : #include "oper/interface_common.h"
25 : #include "oper/mirror_table.h"
26 : #include "ksync/ksync_index.h"
27 : #include "interface_ksync.h"
28 : #include "vr_interface.h"
29 : #include "vhost.h"
30 : #include "pkt/pkt_handler.h"
31 : #include "vrouter/ksync/nexthop_ksync.h"
32 : #include "vrouter/ksync/mirror_ksync.h"
33 : #include "vrouter/ksync/ksync_init.h"
34 :
35 : // Name of clone device for creating tap interface
36 : #define TUN_INTF_CLONE_DEV "/dev/net/tun"
37 : #define SOCK_RETRY_COUNT 4
38 :
39 : #define VIF_FAT_FLOW_ENCODE_AGGR_PROTO_PORT(prefix_aggr, ignore_addr, protocol, port) \
40 : (((prefix_aggr) << 28) | \
41 : ((ignore_addr) << 24) | \
42 : ((protocol) << 16) | \
43 : (port))
44 :
45 26 : InterfaceKSyncEntry::InterfaceKSyncEntry(InterfaceKSyncObject *obj,
46 : const InterfaceKSyncEntry *entry,
47 26 : uint32_t index) :
48 26 : KSyncNetlinkDBEntry(index), analyzer_name_(entry->analyzer_name_),
49 26 : drop_new_flows_(entry->drop_new_flows_),
50 26 : dhcp_enable_(entry->dhcp_enable_),
51 26 : dhcp_enable_v6_(entry->dhcp_enable_v6_),
52 26 : fd_(kInvalidIndex),
53 26 : flow_key_nh_id_(entry->flow_key_nh_id_),
54 26 : has_service_vlan_(entry->has_service_vlan_),
55 26 : interface_id_(entry->interface_id_),
56 26 : interface_name_(entry->interface_name_),
57 26 : ip_(entry->ip_), primary_ip6_(entry->primary_ip6_),
58 26 : hc_active_(false), ipv4_active_(false),
59 26 : layer3_forwarding_(entry->layer3_forwarding_),
60 26 : ksync_obj_(obj), l2_active_(false),
61 26 : metadata_l2_active_(entry->metadata_l2_active_),
62 26 : metadata_ip_active_(entry->metadata_ip_active_),
63 26 : bridging_(entry->bridging_),
64 26 : proxy_arp_mode_(VmInterface::PROXY_ARP_NONE),
65 26 : mac_(entry->mac_),
66 26 : smac_(entry->smac_),
67 26 : mirror_direction_(entry->mirror_direction_),
68 26 : network_id_(entry->network_id_),
69 26 : os_index_(Interface::kInvalidIndex),
70 26 : parent_(entry->parent_),
71 26 : policy_enabled_(entry->policy_enabled_),
72 26 : sub_type_(entry->sub_type_),
73 26 : vmi_device_type_(entry->vmi_device_type_),
74 26 : vmi_type_(entry->vmi_type_),
75 26 : hbs_intf_type_(entry->hbs_intf_type_),
76 26 : type_(entry->type_),
77 26 : rx_vlan_id_(entry->rx_vlan_id_),
78 26 : tx_vlan_id_(entry->tx_vlan_id_),
79 26 : vrf_id_(entry->vrf_id_),
80 26 : multicast_vrf_id_(entry->multicast_vrf_id_),
81 26 : persistent_(entry->persistent_),
82 26 : subtype_(entry->subtype_),
83 26 : xconnect_(entry->xconnect_),
84 26 : no_arp_(entry->no_arp_),
85 26 : encap_type_(entry->encap_type_),
86 26 : display_name_(entry->display_name_),
87 26 : transport_(entry->transport_),
88 26 : flood_unknown_unicast_ (entry->flood_unknown_unicast_),
89 26 : qos_config_(entry->qos_config_),
90 26 : learning_enabled_(entry->learning_enabled_),
91 26 : isid_(entry->isid_), pbb_cmac_vrf_(entry->pbb_cmac_vrf_),
92 26 : pbb_mac_(entry->pbb_mac_), etree_leaf_(entry->etree_leaf_),
93 26 : pbb_interface_(entry->pbb_interface_),
94 26 : vhostuser_mode_(entry->vhostuser_mode_),
95 26 : igmp_enable_(entry->igmp_enable_),
96 26 : mac_ip_learning_enable_(false),
97 26 : os_guid_(entry->os_guid_),
98 78 : xconnect_list_(entry->xconnect_list_) {
99 26 : }
100 :
101 1001 : InterfaceKSyncEntry::InterfaceKSyncEntry(InterfaceKSyncObject *obj,
102 1001 : const Interface *intf) :
103 : KSyncNetlinkDBEntry(kInvalidIndex),
104 1001 : analyzer_name_(),
105 1001 : drop_new_flows_(false),
106 1001 : dhcp_enable_(true),
107 1001 : dhcp_enable_v6_(false),
108 1001 : fd_(-1),
109 1001 : flow_key_nh_id_(0),
110 1001 : has_service_vlan_(false),
111 1001 : interface_id_(intf->id()),
112 1001 : interface_name_(intf->name()),
113 1001 : ip_(0),
114 1001 : hc_active_(false),
115 1001 : ipv4_active_(false),
116 1001 : layer3_forwarding_(true),
117 1001 : ksync_obj_(obj),
118 1001 : l2_active_(false),
119 1001 : metadata_l2_active_(false),
120 1001 : metadata_ip_active_(false),
121 1001 : bridging_(true),
122 1001 : proxy_arp_mode_(VmInterface::PROXY_ARP_NONE),
123 1001 : mac_(),
124 1001 : smac_(),
125 1001 : mirror_direction_(Interface::UNKNOWN),
126 1001 : os_index_(intf->os_index()),
127 1001 : parent_(NULL),
128 1001 : policy_enabled_(false),
129 1001 : sub_type_(InetInterface::VHOST),
130 1001 : vmi_device_type_(VmInterface::DEVICE_TYPE_INVALID),
131 1001 : vmi_type_(VmInterface::VMI_TYPE_INVALID),
132 1001 : hbs_intf_type_(VmInterface::HBS_INTF_INVALID),
133 1001 : type_(intf->type()),
134 1001 : rx_vlan_id_(VmInterface::kInvalidVlanId),
135 1001 : tx_vlan_id_(VmInterface::kInvalidVlanId),
136 1001 : vrf_id_(intf->vrf_id()),
137 1001 : multicast_vrf_id_(VrfEntry::kInvalidIndex),
138 1001 : persistent_(false),
139 1001 : subtype_(PhysicalInterface::INVALID),
140 1001 : xconnect_(NULL),
141 1001 : no_arp_(false),
142 1001 : encap_type_(PhysicalInterface::ETHERNET),
143 1001 : transport_(Interface::TRANSPORT_INVALID),
144 1001 : flood_unknown_unicast_(false), qos_config_(NULL),
145 1001 : learning_enabled_(false), isid_(VmInterface::kInvalidIsid),
146 1001 : pbb_cmac_vrf_(VrfEntry::kInvalidIndex), pbb_mac_(), etree_leaf_(false),
147 1001 : pbb_interface_(false), vhostuser_mode_(VmInterface::vHostUserClient),
148 1001 : igmp_enable_(false), mac_ip_learning_enable_(false),
149 1001 : os_guid_(intf->os_guid()),
150 4004 : xconnect_list_() {
151 :
152 1001 : if (intf->flow_key_nh()) {
153 921 : flow_key_nh_id_ = intf->flow_key_nh()->id();
154 : }
155 1001 : network_id_ = 0;
156 1001 : if (type_ == Interface::VM_INTERFACE) {
157 664 : const VmInterface *vmitf =
158 : static_cast<const VmInterface *>(intf);
159 664 : ip_ = vmitf->primary_ip_addr().to_ulong();
160 664 : primary_ip6_ = vmitf->primary_ip6_addr();
161 664 : network_id_ = vmitf->vxlan_id();
162 664 : rx_vlan_id_ = vmitf->rx_vlan_id();
163 664 : tx_vlan_id_ = vmitf->tx_vlan_id();
164 664 : vhostuser_mode_ = vmitf->vhostuser_mode();
165 664 : if (vmitf->parent()) {
166 127 : InterfaceKSyncEntry tmp(ksync_obj_, vmitf->parent());
167 127 : parent_ = ksync_obj_->GetReference(&tmp);
168 127 : }
169 664 : vmi_device_type_ = vmitf->device_type();
170 664 : vmi_type_ = vmitf->vmi_type();
171 664 : if (vmi_type_ == VmInterface::VHOST) {
172 254 : for (size_t i = 0; i <vmitf->parent_list().size(); i++) {
173 127 : InterfaceKSyncEntry tmp(ksync_obj_, vmitf->parent_list()[i]);
174 127 : xconnect_list_.push_back(ksync_obj_->GetReference(&tmp));
175 127 : }
176 127 : parent_ = NULL;
177 : InterfaceKSyncEntry *xconnect = static_cast<InterfaceKSyncEntry *>
178 127 : (xconnect_list_[0].get());
179 127 : encap_type_ = xconnect->encap_type();
180 127 : no_arp_ = xconnect->no_arp();
181 : }
182 664 : hbs_intf_type_ = vmitf->hbs_intf_type();
183 337 : } else if (type_ == Interface::INET) {
184 0 : const InetInterface *inet_intf =
185 : static_cast<const InetInterface *>(intf);
186 0 : sub_type_ = inet_intf->sub_type();
187 0 : ip_ = inet_intf->ip_addr().to_ulong();
188 0 : if (sub_type_ == InetInterface::VHOST) {
189 0 : InterfaceKSyncEntry tmp(ksync_obj_, inet_intf->xconnect());
190 0 : xconnect_ = ksync_obj_->GetReference(&tmp);
191 : InterfaceKSyncEntry *xconnect = static_cast<InterfaceKSyncEntry *>
192 0 : (xconnect_.get());
193 0 : encap_type_ = xconnect->encap_type();
194 0 : no_arp_ = xconnect->no_arp();
195 0 : }
196 337 : } else if (type_ == Interface::PHYSICAL) {
197 271 : const PhysicalInterface *physical_intf =
198 : static_cast<const PhysicalInterface *>(intf);
199 271 : encap_type_ = physical_intf->encap_type();
200 271 : no_arp_ = physical_intf->no_arp();
201 271 : display_name_ = physical_intf->display_name();
202 271 : ip_ = physical_intf->ip_addr().to_ulong();
203 : }
204 1001 : }
205 :
206 1079 : InterfaceKSyncEntry::~InterfaceKSyncEntry() {
207 1079 : }
208 :
209 407 : KSyncDBObject *InterfaceKSyncEntry::GetObject() const {
210 407 : return ksync_obj_;
211 : }
212 :
213 4012 : bool InterfaceKSyncEntry::IsLess(const KSyncEntry &rhs) const {
214 4012 : const InterfaceKSyncEntry &entry = static_cast
215 : <const InterfaceKSyncEntry &>(rhs);
216 4012 : if (interface_name_ != entry.interface_name_ ) {
217 2005 : return interface_name_ < entry.interface_name_;
218 : } else {
219 2007 : return interface_id_ < entry.interface_id_;
220 : }
221 : }
222 :
223 2304 : std::string InterfaceKSyncEntry::ToString() const {
224 2304 : std::stringstream s;
225 2304 : s << "Interface : " << interface_name_ << " Index : " << interface_id_;
226 : const VrfEntry* vrf =
227 2304 : ksync_obj_->ksync()->agent()->vrf_table()->FindVrfFromId(vrf_id_);
228 2304 : if (vrf) {
229 1940 : s << " Vrf : " << vrf->GetName();
230 : }
231 4608 : return s.str();
232 2304 : }
233 :
234 64 : bool InterfaceKSyncEntry::Sync(DBEntry *e) {
235 64 : Interface *intf = static_cast<Interface *>(e);
236 64 : bool ret = false;
237 :
238 64 : if (hc_active_ != intf->is_hc_active()) {
239 26 : hc_active_ = intf->is_hc_active();
240 26 : ret = true;
241 : }
242 :
243 64 : if (ipv4_active_ != intf->ipv4_active()) {
244 26 : ipv4_active_ = intf->ipv4_active();
245 26 : ret = true;
246 : }
247 :
248 64 : if (l2_active_ != intf->l2_active()) {
249 26 : l2_active_ = intf->l2_active();
250 26 : ret = true;
251 : }
252 :
253 64 : if (os_index_ != intf->os_index()) {
254 24 : os_index_ = intf->os_index();
255 24 : ret = true;
256 : }
257 :
258 64 : if (intf->type() == Interface::VM_INTERFACE) {
259 54 : VmInterface *vm_port = static_cast<VmInterface *>(intf);
260 54 : if (vmi_device_type_ != vm_port->device_type()) {
261 0 : vmi_device_type_ = vm_port->device_type();
262 0 : ret = true;
263 : }
264 :
265 54 : if (vmi_type_ != vm_port->vmi_type()) {
266 0 : vmi_type_ = vm_port->vmi_type();
267 0 : ret = true;
268 : }
269 :
270 54 : if (hbs_intf_type_ != vm_port->hbs_intf_type()) {
271 0 : hbs_intf_type_ = vm_port->hbs_intf_type();
272 0 : ret = true;
273 : }
274 :
275 54 : if (drop_new_flows_ != vm_port->drop_new_flows()) {
276 0 : drop_new_flows_ = vm_port->drop_new_flows();
277 0 : ret = true;
278 : }
279 :
280 54 : if (dhcp_enable_ != vm_port->dhcp_enabled()) {
281 2 : dhcp_enable_ = vm_port->dhcp_enabled();
282 2 : ret = true;
283 : }
284 :
285 54 : if (dhcp_enable_v6_ != vm_port->dhcp_enabled_v6()) {
286 28 : dhcp_enable_v6_ = vm_port->dhcp_enabled_v6();
287 28 : ret = true;
288 : }
289 :
290 54 : if (ip_ != vm_port->primary_ip_addr().to_ulong()) {
291 0 : ip_ = vm_port->primary_ip_addr().to_ulong();
292 0 : ret = true;
293 : }
294 :
295 54 : if (primary_ip6_ != vm_port->primary_ip6_addr()) {
296 0 : primary_ip6_ = vm_port->primary_ip6_addr();
297 0 : ret = true;
298 : }
299 :
300 54 : if (layer3_forwarding_ != vm_port->layer3_forwarding()) {
301 0 : layer3_forwarding_ = vm_port->layer3_forwarding();
302 0 : ret = true;
303 : }
304 :
305 54 : if (flood_unknown_unicast_ != vm_port->flood_unknown_unicast()) {
306 0 : flood_unknown_unicast_ = vm_port->flood_unknown_unicast();
307 0 : ret = true;
308 : }
309 :
310 54 : if (bridging_ != vm_port->bridging()) {
311 31 : bridging_ = vm_port->bridging();
312 31 : ret = true;
313 : }
314 :
315 54 : if (proxy_arp_mode_ != vm_port->proxy_arp_mode()) {
316 0 : proxy_arp_mode_ = vm_port->proxy_arp_mode();
317 0 : ret = true;
318 : }
319 :
320 54 : if (rx_vlan_id_ != vm_port->rx_vlan_id()) {
321 0 : rx_vlan_id_ = vm_port->rx_vlan_id();
322 0 : ret = true;
323 : }
324 :
325 54 : if (tx_vlan_id_ != vm_port->tx_vlan_id()) {
326 0 : tx_vlan_id_ = vm_port->tx_vlan_id();
327 0 : ret = true;
328 : }
329 :
330 54 : if (vhostuser_mode_ != vm_port->vhostuser_mode()) {
331 0 : vhostuser_mode_ = vm_port->vhostuser_mode();
332 0 : ret = true;
333 : }
334 :
335 54 : KSyncEntryPtr parent = NULL;
336 54 : if (vm_port->parent()) {
337 5 : InterfaceKSyncEntry tmp(ksync_obj_, vm_port->parent());
338 5 : parent = ksync_obj_->GetReference(&tmp);
339 5 : }
340 :
341 54 : if (parent_ != parent) {
342 5 : parent_ = parent;
343 5 : ret = true;
344 : }
345 :
346 54 : if (metadata_l2_active_ !=
347 54 : vm_port->metadata_l2_active()) {
348 14 : metadata_l2_active_ =
349 14 : vm_port->metadata_l2_active();
350 14 : ret = true;
351 : }
352 :
353 54 : if (metadata_ip_active_ !=
354 54 : vm_port->metadata_ip_active()) {
355 17 : metadata_ip_active_ =
356 17 : vm_port->metadata_ip_active();
357 17 : ret = true;
358 : }
359 :
360 54 : if (learning_enabled_ != vm_port->learning_enabled()) {
361 0 : learning_enabled_ = vm_port->learning_enabled();
362 0 : ret = true;
363 : }
364 :
365 54 : if (pbb_interface_ != vm_port->pbb_interface()) {
366 0 : pbb_interface_ = vm_port->pbb_interface();
367 0 : ret = true;
368 : }
369 :
370 54 : if (l2_active_ && pbb_interface_ && isid_ != vm_port->GetIsid()) {
371 0 : isid_ = vm_port->GetIsid();
372 0 : ret = true;
373 : }
374 :
375 54 : if (l2_active_ && pbb_interface_ &&
376 0 : pbb_cmac_vrf_ != vm_port->GetPbbVrf()) {
377 0 : pbb_cmac_vrf_ = vm_port->GetPbbVrf();
378 0 : ret = true;
379 : }
380 :
381 54 : if (etree_leaf_ != vm_port->etree_leaf()) {
382 0 : etree_leaf_ = vm_port->etree_leaf();
383 0 : ret = true;
384 : }
385 :
386 54 : if (igmp_enable_ != vm_port->igmp_enabled()) {
387 0 : igmp_enable_ = vm_port->igmp_enabled();
388 0 : ret = true;
389 : }
390 :
391 54 : if (mac_ip_learning_enable_ != vm_port->mac_ip_learning_enable()) {
392 0 : mac_ip_learning_enable_ = vm_port->mac_ip_learning_enable();
393 0 : ret = true;
394 : }
395 54 : }
396 :
397 64 : uint32_t vrf_id = VIF_VRF_INVALID;
398 64 : uint32_t multicast_vrf_id = VIF_VRF_INVALID;
399 64 : bool policy_enabled = false;
400 64 : std::string analyzer_name;
401 64 : Interface::MirrorDirection mirror_direction = Interface::UNKNOWN;
402 64 : bool has_service_vlan = false;
403 64 : if (l2_active_ || ipv4_active_ || metadata_l2_active_ || metadata_ip_active_) {
404 41 : vrf_id = intf->vrf_id();
405 41 : if (vrf_id == VrfEntry::kInvalidIndex) {
406 3 : vrf_id = VIF_VRF_INVALID;
407 : }
408 :
409 41 : if (intf->type() == Interface::VM_INTERFACE) {
410 31 : VmInterface *vm_port = static_cast<VmInterface *>(intf);
411 31 : if (vm_port->forwarding_vrf()) {
412 31 : vrf_id = vm_port->forwarding_vrf()->vrf_id();
413 : }
414 :
415 31 : if (vmi_type_ != VmInterface::VHOST) {
416 28 : multicast_vrf_id = intf->vrf_id();
417 28 : if (pbb_interface_ && l2_active_) {
418 0 : multicast_vrf_id = vm_port->GetPbbVrf();;
419 : }
420 :
421 28 : if (multicast_vrf_id == VrfEntry::kInvalidIndex) {
422 0 : multicast_vrf_id = VIF_VRF_INVALID;
423 : }
424 : }
425 :
426 31 : has_service_vlan = vm_port->HasServiceVlan();
427 31 : policy_enabled = vm_port->policy_enabled();
428 31 : analyzer_name = vm_port->GetAnalyzer();
429 31 : mirror_direction = vm_port->mirror_direction();
430 31 : if (network_id_ != vm_port->vxlan_id()) {
431 6 : network_id_ = vm_port->vxlan_id();
432 6 : ret = true;
433 : }
434 : }
435 : }
436 :
437 64 : if (intf->type() == Interface::INET) {
438 0 : InetInterface *vhost = static_cast<InetInterface *>(intf);
439 0 : sub_type_ = vhost->sub_type();
440 :
441 0 : if (ip_ != vhost->ip_addr().to_ulong()) {
442 0 : ip_ = vhost->ip_addr().to_ulong();
443 0 : ret = true;
444 : }
445 :
446 0 : InetInterface *inet_interface = static_cast<InetInterface *>(intf);
447 0 : if (sub_type_ == InetInterface::VHOST) {
448 0 : KSyncEntryPtr xconnect = NULL;
449 0 : if (!inet_interface->xconnect()) {
450 0 : InterfaceKSyncEntry tmp(ksync_obj_, inet_interface->xconnect());
451 0 : xconnect = ksync_obj_->GetReference(&tmp);
452 0 : }
453 0 : if(xconnect) {
454 0 : if (xconnect_ != xconnect) {
455 0 : xconnect_ = xconnect;
456 0 : ret = true;
457 : }
458 : }
459 0 : }
460 : }
461 :
462 64 : KSyncEntryPtr qos_config = NULL;
463 : QosConfigKSyncObject *qos_object =
464 64 : static_cast<InterfaceKSyncObject *>(ksync_obj_)->ksync()->
465 64 : qos_config_ksync_obj();
466 64 : if (intf->qos_config() != NULL) {
467 0 : QosConfigKSyncEntry tmp(qos_object, intf->qos_config());
468 0 : qos_config = qos_object->GetReference(&tmp);
469 0 : }
470 64 : if (qos_config != qos_config_) {
471 0 : qos_config_ = qos_config;
472 0 : ret = true;
473 : }
474 :
475 64 : if (vrf_id != vrf_id_) {
476 34 : vrf_id_ = vrf_id;
477 34 : ret = true;
478 : }
479 :
480 64 : if (multicast_vrf_id_ != multicast_vrf_id) {
481 40 : multicast_vrf_id_ = multicast_vrf_id;
482 40 : ret = true;
483 : }
484 :
485 64 : if (policy_enabled_ != policy_enabled) {
486 14 : policy_enabled_ = policy_enabled;
487 14 : ret = true;
488 : }
489 :
490 64 : if (analyzer_name_ != analyzer_name) {
491 0 : analyzer_name_ = analyzer_name;
492 0 : ret = true;
493 : }
494 :
495 64 : if (mirror_direction_ != mirror_direction) {
496 0 : mirror_direction_ = mirror_direction;
497 0 : ret = true;
498 : }
499 :
500 64 : if (has_service_vlan_ != has_service_vlan) {
501 0 : has_service_vlan_ = has_service_vlan;
502 0 : ret = true;
503 : }
504 :
505 64 : InterfaceTable *table = static_cast<InterfaceTable *>(intf->get_table());
506 64 : MacAddress dmac;
507 :
508 64 : switch (intf->type()) {
509 54 : case Interface::VM_INTERFACE:
510 : {
511 54 : const VmInterface *vm_intf = static_cast<const VmInterface *>(intf);
512 54 : if (fat_flow_list_.list_ != vm_intf->fat_flow_list().list_) {
513 2 : fat_flow_list_ = vm_intf->fat_flow_list();
514 2 : ret = true;
515 : }
516 54 : vm_intf->BuildFatFlowExcludeList(&fat_flow_exclude_list_);
517 54 : std::set<MacAddress> aap_mac_list;
518 54 : for (VmInterface::AllowedAddressPairSet::iterator aap_it =
519 54 : vm_intf->allowed_address_pair_list().list_.begin();
520 54 : aap_it != vm_intf->allowed_address_pair_list().list_.end();
521 0 : ++aap_it) {
522 0 : aap_mac_list.insert(aap_it->mac_);
523 : }
524 54 : if (aap_mac_list_ != aap_mac_list) {
525 0 : aap_mac_list_.swap(aap_mac_list);
526 0 : ret = true;
527 : }
528 54 : MacAddress pbb_mac;
529 54 : if (pbb_interface_) {
530 0 : pbb_mac = MacAddress(vm_intf->vm_mac());
531 : }
532 54 : if (pbb_mac != pbb_mac_) {
533 0 : pbb_mac_ = pbb_mac;
534 0 : ret = true;
535 : }
536 54 : }
537 57 : case Interface::PACKET:
538 57 : dmac = table->agent()->vrrp_mac();
539 57 : break;
540 :
541 7 : case Interface::PHYSICAL:
542 : {
543 7 : dmac = intf->mac();
544 7 : PhysicalInterface *phy_intf = static_cast<PhysicalInterface *>(intf);
545 7 : persistent_ = phy_intf->persistent();
546 7 : subtype_ = phy_intf->subtype();
547 7 : break;
548 : }
549 0 : case Interface::INET: {
550 0 : dmac = intf->mac();
551 :
552 0 : bool no_arp = false;
553 0 : PhysicalInterface::EncapType encap = PhysicalInterface::ETHERNET;
554 : InterfaceKSyncEntry *xconnect = static_cast<InterfaceKSyncEntry *>
555 0 : (xconnect_.get());
556 0 : if (xconnect) {
557 0 : no_arp = xconnect->no_arp();
558 0 : encap = xconnect->encap_type();
559 : }
560 :
561 0 : if (no_arp_ != no_arp) {
562 0 : no_arp_ = no_arp;
563 0 : ret = true;
564 : }
565 0 : if (encap_type_ != encap) {
566 0 : encap_type_ = encap;
567 0 : ret = true;
568 : }
569 :
570 0 : break;
571 : }
572 :
573 0 : case Interface::LOGICAL:
574 : case Interface::REMOTE_PHYSICAL:
575 0 : dmac = intf->mac();
576 0 : break;
577 :
578 0 : default:
579 0 : assert(0);
580 : }
581 :
582 64 : if (dmac != mac()) {
583 28 : mac_ = dmac;
584 28 : ret = true;
585 : }
586 :
587 : // In VMWare VCenter mode, interface is assigned using the SMAC
588 : // in packet. Store the SMAC for interface
589 64 : MacAddress smac;
590 118 : if (intf->type() == Interface::VM_INTERFACE &&
591 108 : (ksync_obj_->ksync()->agent()->isVmwareVcenterMode() ||
592 108 : ksync_obj_->ksync()->agent()->server_gateway_mode() ||
593 54 : ksync_obj_->ksync()->agent()->pbb_gateway_mode())) {
594 0 : const VmInterface *vm_intf = static_cast<const VmInterface *>(intf);
595 0 : smac = MacAddress(vm_intf->vm_mac());
596 : }
597 :
598 64 : if (smac != smac_) {
599 0 : smac_ = smac;
600 0 : ret = true;
601 : }
602 :
603 : //Nexthop index gets used in flow key, vrouter just treats
604 : //it as an index and doesnt cross check against existence of nexthop,
605 : //hence there is no need to make sure that nexthop is programmed
606 : //before flow key nexthop index is set in interface
607 : //Nexthop index 0 if set in interface is treated as invalid index,
608 : //and packet would be dropped if such a packet needs to go thru
609 : //flow lookup
610 64 : uint32_t nh_id = 0;
611 64 : if (intf->flow_key_nh()) {
612 36 : nh_id = intf->flow_key_nh()->id();
613 : }
614 64 : if (nh_id != flow_key_nh_id_) {
615 12 : flow_key_nh_id_ = nh_id;
616 12 : ret = true;
617 : }
618 :
619 64 : if (transport_ != intf->transport()) {
620 24 : transport_ = intf->transport();
621 24 : ret = true;
622 : }
623 :
624 64 : if (os_guid_ != intf->os_guid()) {
625 0 : os_guid_ = intf->os_guid();
626 0 : ret = true;
627 : }
628 :
629 64 : return ret;
630 64 : }
631 :
632 47 : KSyncEntry *InterfaceKSyncEntry::UnresolvedReference() {
633 47 : if (qos_config_.get() && qos_config_->IsResolved() == false) {
634 0 : return qos_config_.get();
635 : }
636 :
637 47 : if (type_ == Interface::INET && sub_type_ == InetInterface::VHOST) {
638 0 : if (xconnect_.get() && !xconnect_->IsResolved()) {
639 0 : return xconnect_.get();
640 : }
641 : }
642 :
643 47 : if (type_ != Interface::VM_INTERFACE) {
644 9 : return NULL;
645 : }
646 :
647 38 : if (parent_.get() && !parent_->IsResolved()) {
648 0 : return parent_.get();
649 : }
650 :
651 38 : if (!analyzer_name_.empty()) {
652 : MirrorKSyncObject *mirror_object =
653 0 : ksync_obj_->ksync()->mirror_ksync_obj();
654 0 : MirrorKSyncEntry mksync1(mirror_object, analyzer_name_);
655 : MirrorKSyncEntry *mirror =
656 0 : static_cast<MirrorKSyncEntry *>(mirror_object->GetReference(&mksync1));
657 0 : if (mirror && !mirror->IsResolved() &&
658 0 : mirror->mirror_index() == MirrorTable::kInvalidIndex) {
659 0 : return mirror;
660 : }
661 0 : }
662 38 : return NULL;
663 : }
664 :
665 71 : bool IsValidOsIndex(size_t os_index, Interface::Type type, uint16_t vlan_id,
666 : VmInterface::VmiType vmi_type, Interface::Transport transport) {
667 71 : if (transport != Interface::TRANSPORT_ETHERNET) {
668 11 : return true;
669 : }
670 :
671 60 : if (os_index != Interface::kInvalidIndex)
672 60 : return true;
673 :
674 0 : if (type == Interface::VM_INTERFACE &&
675 : vlan_id != VmInterface::kInvalidVlanId) {
676 0 : return true;
677 : }
678 :
679 0 : if (vmi_type == VmInterface::GATEWAY ||
680 : vmi_type == VmInterface::REMOTE_VM) {
681 0 : return true;
682 : }
683 :
684 0 : return false;
685 : }
686 :
687 73 : int InterfaceKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
688 73 : vr_interface_req encoder;
689 : int encode_len;
690 73 : uint32_t vrf_id = vrf_id_;
691 73 : std::vector<int32_t> cross_connect_idx_list;
692 :
693 73 : uint32_t flags = 0;
694 73 : encoder.set_h_op(op);
695 73 : if (op == sandesh_op::DEL) {
696 26 : encoder.set_vifr_idx(interface_id_);
697 26 : int error = 0;
698 26 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
699 26 : assert(error == 0);
700 26 : assert(encode_len <= buf_len);
701 26 : return encode_len;
702 : }
703 :
704 47 : if (qos_config_.get() != NULL) {
705 : QosConfigKSyncEntry *qos_config =
706 0 : static_cast<QosConfigKSyncEntry *>(qos_config_.get());
707 0 : encoder.set_vifr_qos_map_index(qos_config->id());
708 : } else {
709 47 : encoder.set_vifr_qos_map_index(-1);
710 : }
711 :
712 47 : if (etree_leaf_ == false) {
713 47 : flags |= VIF_FLAG_ETREE_ROOT;
714 : }
715 :
716 47 : switch (type_) {
717 38 : case Interface::VM_INTERFACE: {
718 38 : if (vmi_device_type_ == VmInterface::TOR)
719 4 : return 0;
720 34 : if (drop_new_flows_) {
721 0 : flags |= VIF_FLAG_DROP_NEW_FLOWS;
722 : }
723 34 : if (dhcp_enable_ || dhcp_enable_v6_) {
724 30 : flags |= VIF_FLAG_DHCP_ENABLED;
725 : }
726 34 : if (bridging_) {
727 19 : flags |= VIF_FLAG_L2_ENABLED;
728 : }
729 34 : if (vmi_type_ == VmInterface::GATEWAY) {
730 0 : flags |= VIF_FLAG_NO_ARP_PROXY;
731 : }
732 34 : if (hbs_intf_type_ != VmInterface::HBS_INTF_INVALID) {
733 0 : flags |= (hbs_intf_type_ == VmInterface::HBS_INTF_RIGHT)?
734 : VIF_FLAG_HBS_RIGHT:VIF_FLAG_HBS_LEFT;
735 : }
736 34 : if (flood_unknown_unicast_) {
737 0 : flags |= VIF_FLAG_UNKNOWN_UC_FLOOD;
738 : }
739 34 : if (learning_enabled_) {
740 0 : flags |= VIF_FLAG_MAC_LEARN;
741 : }
742 34 : if (proxy_arp_mode_ == VmInterface::PROXY_ARP_UNRESTRICTED) {
743 0 : flags |= VIF_FLAG_MAC_PROXY;
744 : }
745 34 : if (igmp_enable_) {
746 0 : flags |= VIF_FLAG_IGMP_ENABLED;
747 : }
748 34 : if (mac_ip_learning_enable_) {
749 0 : flags |= VIF_FLAG_MAC_IP_LEARNING;
750 : }
751 34 : MacAddress mac;
752 34 : if (parent_.get() != NULL) {
753 3 : encoder.set_vifr_type(VIF_TYPE_VIRTUAL_VLAN);
754 3 : if ((vmi_type_ == VmInterface::GATEWAY ||
755 3 : vmi_type_ == VmInterface::REMOTE_VM) &&
756 0 : tx_vlan_id_ == VmInterface::kInvalidVlanId) {
757 : //By default in case of gateway, untagged packet
758 : //would be considered as belonging to interface
759 : //at tag 0
760 0 : encoder.set_vifr_vlan_id(0);
761 0 : encoder.set_vifr_ovlan_id(0);
762 : } else {
763 3 : encoder.set_vifr_vlan_id(rx_vlan_id_);
764 3 : encoder.set_vifr_ovlan_id(tx_vlan_id_);
765 : }
766 : InterfaceKSyncEntry *parent =
767 3 : (static_cast<InterfaceKSyncEntry *> (parent_.get()));
768 3 : encoder.set_vifr_parent_vif_idx(parent->interface_id());
769 3 : mac = parent->mac();
770 : } else {
771 31 : mac = ksync_obj_->ksync()->agent()->vrrp_mac();
772 31 : encoder.set_vifr_type(VIF_TYPE_VIRTUAL);
773 : }
774 :
775 34 : if (vmi_type_ == VmInterface::VHOST) {
776 3 : encoder.set_vifr_type(VIF_TYPE_HOST);
777 3 : encoder.set_vifr_loopback_ip(ksync_obj_->ksync()->agent()->loopback_ip().to_ulong());
778 3 : if (xconnect_list_.empty() == false) {
779 6 : for (size_t i = 0; i < xconnect_list_.size(); i++) {
780 : InterfaceKSyncEntry *xconnect =
781 3 : static_cast<InterfaceKSyncEntry *>(xconnect_list_[i].get());
782 3 : cross_connect_idx_list.push_back(xconnect->os_index_);
783 : }
784 : } else {
785 0 : cross_connect_idx_list.push_back(Interface::kInvalidIndex);
786 : }
787 3 : encoder.set_vifr_cross_connect_idx(cross_connect_idx_list);
788 : }
789 :
790 : std::vector<int8_t> intf_mac((int8_t *)mac,
791 34 : (int8_t *)mac + mac.size());
792 34 : encoder.set_vifr_mac(intf_mac);
793 :
794 102 : if (ksync_obj_->ksync()->agent()->isVmwareVcenterMode() ||
795 68 : ((ksync_obj_->ksync()->agent()->server_gateway_mode() ||
796 34 : ksync_obj_->ksync()->agent()->pbb_gateway_mode()) &&
797 0 : vmi_type_ == VmInterface::REMOTE_VM)) {
798 0 : std::vector<int8_t> mac;
799 0 : mac.insert(mac.begin(), (const int8_t *)smac(),
800 0 : (const int8_t *)smac() + smac().size());
801 0 : for (std::set<MacAddress>::iterator it = aap_mac_list_.begin();
802 0 : it != aap_mac_list_.end(); ++it) {
803 0 : mac.insert(mac.end(), (const int8_t *)(*it),
804 0 : (const int8_t *)(*it) + (*it).size());
805 : }
806 0 : encoder.set_vifr_src_mac(mac);
807 0 : flags |= VIF_FLAG_MIRROR_NOTAG;
808 0 : }
809 :
810 : // Disable fat-flow when health-check status is inactive
811 : // If fat-flow is active, then following problem happens,
812 : // 1. Health Check Request from vhost0 interface creates a flow
813 : // 2. Health Check response is received from VMI with fat-flow
814 : // - Response creates new flow due to fat-flow configuration
815 : // - If health-check status is inactive routes for interface are
816 : // withdrawn
817 : // - Flow created from response fails due to missing routes
818 : // If fat-flow is disabled, the reverse packet hits flow created (1)
819 : // and succeeds
820 34 : if (hc_active_ && fat_flow_list_.list_.size() != 0) {
821 4 : std::vector<int32_t> fat_flow_protocol_port_list;
822 4 : std::vector<uint64_t> fat_flow_src_prefix_h_list;
823 4 : std::vector<uint64_t> fat_flow_src_prefix_l_list;
824 4 : std::vector<int8_t> fat_flow_src_prefix_mask_list;
825 4 : std::vector<int8_t> fat_flow_src_aggregate_plen_list;
826 4 : std::vector<uint64_t> fat_flow_dst_prefix_h_list;
827 4 : std::vector<uint64_t> fat_flow_dst_prefix_l_list;
828 4 : std::vector<int8_t> fat_flow_dst_prefix_mask_list;
829 4 : std::vector<int8_t> fat_flow_dst_aggregate_plen_list;
830 : uint64_t tmp_ip6[2];
831 :
832 4 : for (VmInterface::FatFlowEntrySet::const_iterator it =
833 4 : fat_flow_list_.list_.begin();
834 10 : it != fat_flow_list_.list_.end(); it++) {
835 6 : if (it->prefix_aggregate == VmInterface::AGGREGATE_NONE) {
836 6 : fat_flow_protocol_port_list.push_back(
837 6 : VIF_FAT_FLOW_ENCODE_AGGR_PROTO_PORT(it->prefix_aggregate,
838 : it->ignore_address,
839 : it->protocol,
840 : it->port));
841 6 : fat_flow_src_prefix_l_list.push_back(0);
842 6 : fat_flow_src_prefix_h_list.push_back(0);
843 6 : fat_flow_src_prefix_mask_list.push_back(0);
844 6 : fat_flow_src_aggregate_plen_list.push_back(0);
845 6 : fat_flow_dst_prefix_l_list.push_back(0);
846 6 : fat_flow_dst_prefix_h_list.push_back(0);
847 6 : fat_flow_dst_prefix_mask_list.push_back(0);
848 6 : fat_flow_dst_aggregate_plen_list.push_back(0);
849 0 : } else if ((it->prefix_aggregate ==
850 0 : VmInterface::AGGREGATE_SRC_IPV4) ||
851 0 : (it->prefix_aggregate ==
852 0 : VmInterface::AGGREGATE_DST_IPV4) ||
853 0 : (it->prefix_aggregate ==
854 : VmInterface::AGGREGATE_SRC_DST_IPV4)) {
855 0 : fat_flow_protocol_port_list.push_back(
856 0 : VIF_FAT_FLOW_ENCODE_AGGR_PROTO_PORT(it->prefix_aggregate,
857 : it->ignore_address,
858 : it->protocol,
859 : it->port));
860 0 : fat_flow_src_prefix_l_list.push_back(
861 0 : (uint64_t) htonl(it->src_prefix.to_v4().to_ulong()));
862 0 : fat_flow_src_prefix_h_list.push_back(0);
863 0 : fat_flow_src_prefix_mask_list.push_back(it->src_prefix_mask);
864 0 : fat_flow_src_aggregate_plen_list.push_back(it->src_aggregate_plen);
865 0 : fat_flow_dst_prefix_l_list.push_back(
866 0 : (uint64_t) htonl(it->dst_prefix.to_v4().to_ulong()));
867 0 : fat_flow_dst_prefix_h_list.push_back(0);
868 0 : fat_flow_dst_prefix_mask_list.push_back(it->dst_prefix_mask);
869 0 : fat_flow_dst_aggregate_plen_list.push_back(it->dst_aggregate_plen);
870 : } else {
871 0 : fat_flow_protocol_port_list.push_back(
872 0 : VIF_FAT_FLOW_ENCODE_AGGR_PROTO_PORT(it->prefix_aggregate,
873 : it->ignore_address,
874 : it->protocol,
875 : it->port));
876 0 : if (it->prefix_aggregate == VmInterface::AGGREGATE_DST_IPV6) {
877 : // src prefix is not valid
878 0 : fat_flow_src_prefix_h_list.push_back(0);
879 0 : fat_flow_src_prefix_l_list.push_back(0);
880 0 : fat_flow_src_prefix_mask_list.push_back(0);
881 0 : fat_flow_src_aggregate_plen_list.push_back(0);
882 : } else {
883 0 : Ip6AddressToU64Array(it->src_prefix.to_v6(), tmp_ip6, 2);
884 0 : fat_flow_src_prefix_h_list.push_back(tmp_ip6[0]);
885 0 : fat_flow_src_prefix_l_list.push_back(tmp_ip6[1]);
886 0 : fat_flow_src_prefix_mask_list.push_back(
887 0 : it->src_prefix_mask);
888 0 : fat_flow_src_aggregate_plen_list.push_back(
889 0 : it->src_aggregate_plen);
890 : }
891 0 : if (it->prefix_aggregate == VmInterface::AGGREGATE_SRC_IPV6) {
892 : // dst prefix is not valid
893 0 : fat_flow_dst_prefix_h_list.push_back(0);
894 0 : fat_flow_dst_prefix_l_list.push_back(0);
895 0 : fat_flow_dst_prefix_mask_list.push_back(0);
896 0 : fat_flow_dst_aggregate_plen_list.push_back(0);
897 : } else {
898 0 : Ip6AddressToU64Array(it->dst_prefix.to_v6(), tmp_ip6, 2);
899 0 : fat_flow_dst_prefix_h_list.push_back(tmp_ip6[0]);
900 0 : fat_flow_dst_prefix_l_list.push_back(tmp_ip6[1]);
901 0 : fat_flow_dst_prefix_mask_list.push_back(it->dst_prefix_mask);
902 0 : fat_flow_dst_aggregate_plen_list.push_back(
903 0 : it->dst_aggregate_plen);
904 : }
905 : }
906 : }
907 4 : encoder.set_vifr_fat_flow_protocol_port(
908 : fat_flow_protocol_port_list);
909 4 : encoder.set_vifr_fat_flow_src_prefix_h(
910 : fat_flow_src_prefix_h_list);
911 4 : encoder.set_vifr_fat_flow_src_prefix_l(
912 : fat_flow_src_prefix_l_list);
913 4 : encoder.set_vifr_fat_flow_src_prefix_mask(
914 : fat_flow_src_prefix_mask_list);
915 4 : encoder.set_vifr_fat_flow_src_aggregate_plen(
916 : fat_flow_src_aggregate_plen_list);
917 4 : encoder.set_vifr_fat_flow_dst_prefix_h(
918 : fat_flow_dst_prefix_h_list);
919 4 : encoder.set_vifr_fat_flow_dst_prefix_l(
920 : fat_flow_dst_prefix_l_list);
921 4 : encoder.set_vifr_fat_flow_dst_prefix_mask(
922 : fat_flow_dst_prefix_mask_list);
923 4 : encoder.set_vifr_fat_flow_dst_aggregate_plen(
924 : fat_flow_dst_aggregate_plen_list);
925 :
926 : encoder.set_vifr_fat_flow_exclude_ip_list
927 4 : (fat_flow_exclude_list_.fat_flow_v4_exclude_list_);
928 : encoder.set_vifr_fat_flow_exclude_ip6_u_list
929 4 : (fat_flow_exclude_list_.fat_flow_v6_exclude_upper_list_);
930 : encoder.set_vifr_fat_flow_exclude_ip6_l_list
931 4 : (fat_flow_exclude_list_.fat_flow_v6_exclude_lower_list_);
932 : encoder.set_vifr_fat_flow_exclude_ip6_plen_list
933 4 : (fat_flow_exclude_list_.fat_flow_v6_exclude_plen_list_);
934 4 : }
935 :
936 34 : if (pbb_interface_) {
937 : std::vector<int8_t> pbb_mac((int8_t *)pbb_mac_,
938 0 : (int8_t *)pbb_mac_ + mac.size());
939 0 : encoder.set_vifr_pbb_mac(pbb_mac);
940 0 : encoder.set_vifr_isid(isid_);
941 0 : if (pbb_cmac_vrf_ != VrfEntry::kInvalidIndex) {
942 0 : vrf_id = pbb_cmac_vrf_;
943 : }
944 0 : }
945 :
946 34 : if (!primary_ip6_.is_unspecified()) {
947 : uint64_t data[2];
948 31 : Ip6AddressToU64Array(primary_ip6_, data, 2);
949 31 : encoder.set_vifr_ip6_u(data[0]);
950 31 : encoder.set_vifr_ip6_l(data[1]);
951 : }
952 34 : encoder.set_vifr_vhostuser_mode(vhostuser_mode_);
953 34 : break;
954 34 : }
955 :
956 6 : case Interface::PHYSICAL: {
957 6 : encoder.set_vifr_type(VIF_TYPE_PHYSICAL);
958 6 : flags |= VIF_FLAG_L3_ENABLED;
959 6 : flags |= VIF_FLAG_L2_ENABLED;
960 6 : if (!persistent_) {
961 5 : flags |= VIF_FLAG_VHOST_PHYS;
962 : }
963 :
964 6 : if (subtype_ == PhysicalInterface::VMWARE ||
965 12 : ksync_obj_->ksync()->agent()->server_gateway_mode() ||
966 6 : ksync_obj_->ksync()->agent()->pbb_gateway_mode()) {
967 0 : flags |= VIF_FLAG_PROMISCOUS;
968 : }
969 6 : if (subtype_ == PhysicalInterface::CONFIG) {
970 1 : flags |= VIF_FLAG_NATIVE_VLAN_TAG;
971 1 : flags |= VIF_FLAG_FAB_GW_MODE;
972 : }
973 6 : encoder.set_vifr_name(display_name_);
974 :
975 6 : AgentParam *params = ksync_obj_->ksync()->agent()->params();
976 6 : std::vector<int16_t> nic_queue_list;
977 6 : for (std::set<uint16_t>::const_iterator it =
978 6 : params->nic_queue_list().begin();
979 6 : it != params->nic_queue_list().end(); it++) {
980 0 : nic_queue_list.push_back(*it);
981 : }
982 6 : encoder.set_vifr_hw_queues(nic_queue_list);
983 6 : break;
984 6 : }
985 :
986 0 : case Interface::INET: {
987 0 : switch (sub_type_) {
988 0 : case InetInterface::SIMPLE_GATEWAY:
989 0 : encoder.set_vifr_type(VIF_TYPE_GATEWAY);
990 0 : break;
991 0 : case InetInterface::LINK_LOCAL:
992 0 : encoder.set_vifr_type(VIF_TYPE_XEN_LL_HOST);
993 0 : break;
994 0 : case InetInterface::VHOST:
995 0 : encoder.set_vifr_type(VIF_TYPE_HOST);
996 0 : encoder.set_vifr_loopback_ip(ksync_obj_->ksync()->agent()->loopback_ip().to_ulong());
997 0 : if (xconnect_.get()) {
998 : InterfaceKSyncEntry *xconnect =
999 0 : static_cast<InterfaceKSyncEntry *>(xconnect_.get());
1000 0 : cross_connect_idx_list.push_back(xconnect->os_index_);
1001 : } else {
1002 0 : cross_connect_idx_list.push_back(Interface::kInvalidIndex);
1003 : }
1004 0 : encoder.set_vifr_cross_connect_idx(cross_connect_idx_list);
1005 0 : break;
1006 0 : default:
1007 0 : encoder.set_vifr_type(VIF_TYPE_HOST);
1008 0 : break;
1009 : }
1010 0 : flags |= VIF_FLAG_L3_ENABLED;
1011 0 : flags |= VIF_FLAG_L2_ENABLED;
1012 0 : break;
1013 : }
1014 :
1015 3 : case Interface::PACKET: {
1016 3 : encoder.set_vifr_type(VIF_TYPE_AGENT);
1017 3 : flags |= VIF_FLAG_L3_ENABLED;
1018 3 : break;
1019 : }
1020 0 : default:
1021 0 : assert(0);
1022 : }
1023 :
1024 43 : if (layer3_forwarding_) {
1025 43 : flags |= VIF_FLAG_L3_ENABLED;
1026 43 : if (policy_enabled_) {
1027 12 : flags |= VIF_FLAG_POLICY_ENABLED;
1028 : }
1029 43 : MirrorKSyncObject* obj = ksync_obj_->ksync()->mirror_ksync_obj();
1030 43 : if (!analyzer_name_.empty()) {
1031 0 : uint16_t idx = obj->GetIdx(analyzer_name_);
1032 0 : if (Interface::MIRROR_TX == mirror_direction_) {
1033 0 : flags |= VIF_FLAG_MIRROR_TX;
1034 0 : } else if (Interface::MIRROR_RX == mirror_direction_) {
1035 0 : flags |= VIF_FLAG_MIRROR_RX;
1036 : } else {
1037 0 : flags |= VIF_FLAG_MIRROR_RX;
1038 0 : flags |= VIF_FLAG_MIRROR_TX;
1039 : }
1040 0 : encoder.set_vifr_mir_id(idx);
1041 :
1042 : const VrfEntry* vrf =
1043 0 : ksync_obj_->ksync()->agent()->vrf_table()->FindVrfFromId(vrf_id_);
1044 0 : if (vrf && vrf->vn()) {
1045 0 : const std::string &vn_name = vrf->vn()->GetName() ;
1046 : // TLV for RX Mirror
1047 0 : std::vector<int8_t> srcdata;
1048 0 : srcdata.push_back(FlowEntry::PCAP_SOURCE_VN);
1049 0 : srcdata.push_back(vn_name.size());
1050 0 : srcdata.insert(srcdata.end(), vn_name.begin(),
1051 : vn_name.end());
1052 0 : srcdata.push_back(FlowEntry::PCAP_TLV_END);
1053 0 : srcdata.push_back(0x0);
1054 0 : encoder.set_vifr_in_mirror_md(srcdata);
1055 : // TLV for TX Mirror
1056 0 : std::vector<int8_t> destdata;
1057 0 : destdata.push_back(FlowEntry::PCAP_DEST_VN);
1058 0 : destdata.push_back(vn_name.size());
1059 0 : destdata.insert(destdata.end(), vn_name.begin(),
1060 : vn_name.end());
1061 0 : destdata.push_back(FlowEntry::PCAP_TLV_END);
1062 0 : destdata.push_back(0x0);
1063 0 : encoder.set_vifr_out_mirror_md(destdata);
1064 0 : }
1065 : }
1066 :
1067 43 : if (has_service_vlan_) {
1068 0 : flags |= VIF_FLAG_SERVICE_IF;
1069 : }
1070 : }
1071 :
1072 86 : encoder.set_vifr_mac(std::vector<int8_t>((const int8_t *)mac(),
1073 43 : (const int8_t *)mac() + mac().size()));
1074 :
1075 43 : switch(transport_) {
1076 43 : case Interface::TRANSPORT_ETHERNET: {
1077 43 : encoder.set_vifr_transport(VIF_TRANSPORT_ETH);
1078 43 : break;
1079 : }
1080 :
1081 0 : case Interface::TRANSPORT_SOCKET: {
1082 0 : encoder.set_vifr_transport(VIF_TRANSPORT_SOCKET);
1083 0 : break;
1084 : }
1085 :
1086 0 : case Interface::TRANSPORT_PMD: {
1087 0 : encoder.set_vifr_transport(VIF_TRANSPORT_PMD);
1088 0 : break;
1089 : }
1090 0 : default:
1091 0 : break;
1092 : }
1093 :
1094 43 : encoder.set_vifr_flags(flags);
1095 :
1096 43 : encoder.set_vifr_vrf(vrf_id);
1097 43 : encoder.set_vifr_mcast_vrf(multicast_vrf_id_);
1098 43 : encoder.set_vifr_idx(interface_id_);
1099 43 : encoder.set_vifr_rid(0);
1100 43 : encoder.set_vifr_os_idx(os_index_);
1101 43 : encoder.set_vifr_mtu(0);
1102 43 : if (type_ != Interface::PHYSICAL) {
1103 37 : encoder.set_vifr_name(interface_name_);
1104 : }
1105 43 : encoder.set_vifr_ip(htonl(ip_));
1106 43 : encoder.set_vifr_nh_id(flow_key_nh_id_);
1107 :
1108 : // GUIDs are used as interface identifiers on Windows
1109 86 : if (os_guid_) {
1110 0 : InterfaceOsParams::IfGuid& os_guid = os_guid_.get();
1111 :
1112 0 : std::vector<int8_t> raw_guid(os_guid.size(), 0);
1113 0 : memcpy(raw_guid.data(), &os_guid, os_guid.size());
1114 :
1115 0 : encoder.set_vifr_if_guid(raw_guid);
1116 0 : }
1117 :
1118 43 : int error = 0;
1119 43 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
1120 43 : if (error != 0) {
1121 0 : LOG(ERROR, "Error <" << error << ">: Failed to encode sandesh buffer");
1122 0 : return 0;
1123 : }
1124 43 : if (encode_len > buf_len) {
1125 0 : LOG(ERROR, "Sandesh buffer exceeds the size limit: " << encode_len
1126 : << ". Skipping it.");
1127 0 : return 0;
1128 : }
1129 43 : return encode_len;
1130 73 : }
1131 :
1132 73 : void InterfaceKSyncEntry::FillObjectLog(sandesh_op::type op,
1133 : KSyncIntfInfo &info) const {
1134 73 : info.set_name(interface_name_);
1135 73 : info.set_idx(interface_id_);
1136 :
1137 73 : if (op == sandesh_op::ADD) {
1138 47 : info.set_operation("ADD/CHANGE");
1139 : } else {
1140 26 : info.set_operation("DELETE");
1141 : }
1142 :
1143 73 : if (op == sandesh_op::ADD) {
1144 47 : info.set_os_idx(os_index_);
1145 47 : info.set_vrf_id(vrf_id_);
1146 47 : info.set_hc_active(hc_active_);
1147 47 : info.set_l2_active(l2_active_);
1148 47 : info.set_active(ipv4_active_);
1149 47 : info.set_policy_enabled(policy_enabled_);
1150 47 : info.set_service_enabled(has_service_vlan_);
1151 47 : info.set_analyzer_name(analyzer_name_);
1152 :
1153 47 : std::vector<KSyncIntfFatFlowInfo> fat_flows;
1154 47 : for (VmInterface::FatFlowEntrySet::const_iterator it =
1155 100 : fat_flow_list_.list_.begin(); it != fat_flow_list_.list_.end();
1156 6 : it++) {
1157 6 : KSyncIntfFatFlowInfo info;
1158 6 : info.set_protocol(it->protocol);
1159 6 : info.set_port(it->port);
1160 6 : info.set_ignore_address(it->ignore_address);
1161 6 : fat_flows.push_back(info);
1162 6 : }
1163 47 : info.set_fat_flows(fat_flows);
1164 : info.set_fat_flow_v4_exclude_list
1165 47 : (fat_flow_exclude_list_.fat_flow_v4_exclude_list_);
1166 : info.set_fat_flow_v6_exclude_upper_list
1167 47 : (fat_flow_exclude_list_.fat_flow_v6_exclude_upper_list_);
1168 : info.set_fat_flow_v6_exclude_lower_list
1169 47 : (fat_flow_exclude_list_.fat_flow_v6_exclude_lower_list_);
1170 : info.set_fat_flow_v6_exclude_plen_list
1171 47 : (fat_flow_exclude_list_.fat_flow_v6_exclude_plen_list_);
1172 47 : }
1173 73 : }
1174 :
1175 47 : int InterfaceKSyncEntry::AddMsg(char *buf, int buf_len) {
1176 47 : KSyncIntfInfo info;
1177 :
1178 47 : FillObjectLog(sandesh_op::ADD, info);
1179 47 : KSYNC_TRACE(Intf, GetObject(), info);
1180 94 : return Encode(sandesh_op::ADD, buf, buf_len);
1181 47 : }
1182 :
1183 26 : int InterfaceKSyncEntry::DeleteMsg(char *buf, int buf_len) {
1184 26 : KSyncIntfInfo info;
1185 26 : FillObjectLog(sandesh_op::DEL, info);
1186 26 : KSYNC_TRACE(Intf, GetObject(), info);
1187 52 : return Encode(sandesh_op::DEL, buf, buf_len);
1188 26 : }
1189 :
1190 21 : int InterfaceKSyncEntry::ChangeMsg(char *buf, int buf_len) {
1191 21 : return AddMsg(buf, buf_len);
1192 : }
1193 :
1194 3 : InterfaceKSyncObject::InterfaceKSyncObject(KSync *ksync) :
1195 3 : KSyncDBObject("KSync Interface"), ksync_(ksync) {
1196 3 : }
1197 :
1198 6 : InterfaceKSyncObject::~InterfaceKSyncObject() {
1199 6 : }
1200 :
1201 3 : void InterfaceKSyncObject::RegisterDBClients() {
1202 3 : RegisterDb(ksync_->agent()->interface_table());
1203 3 : }
1204 :
1205 26 : KSyncEntry *InterfaceKSyncObject::Alloc(const KSyncEntry *entry,
1206 : uint32_t index) {
1207 26 : const InterfaceKSyncEntry *intf =
1208 : static_cast<const InterfaceKSyncEntry *>(entry);
1209 26 : InterfaceKSyncEntry *ksync = new InterfaceKSyncEntry(this, intf, index);
1210 26 : return static_cast<KSyncEntry *>(ksync);
1211 : }
1212 :
1213 26 : KSyncEntry *InterfaceKSyncObject::DBToKSyncEntry(const DBEntry *e) {
1214 26 : const Interface *intf = static_cast<const Interface *>(e);
1215 26 : InterfaceKSyncEntry *key = NULL;
1216 :
1217 26 : switch (intf->type()) {
1218 26 : case Interface::PHYSICAL:
1219 : case Interface::VM_INTERFACE:
1220 : case Interface::PACKET:
1221 : case Interface::INET:
1222 : case Interface::LOGICAL:
1223 : case Interface::REMOTE_PHYSICAL:
1224 26 : key = new InterfaceKSyncEntry(this, intf);
1225 26 : break;
1226 :
1227 0 : default:
1228 0 : assert(0);
1229 : break;
1230 : }
1231 26 : return static_cast<KSyncEntry *>(key);
1232 : }
1233 :
1234 0 : void InterfaceKSyncObject::Init() {
1235 0 : ksync_->agent()->set_test_mode(false);
1236 0 : }
1237 :
1238 3 : void InterfaceKSyncObject::InitTest() {
1239 3 : ksync_->agent()->set_test_mode(true);
1240 3 : }
1241 :
1242 : KSyncDBObject::DBFilterResp
1243 71 : InterfaceKSyncObject::DBEntryFilter(const DBEntry *entry,
1244 : const KSyncDBEntry *ksync) {
1245 :
1246 71 : const Interface *intf = dynamic_cast<const Interface *>(entry);
1247 71 : const VmInterface *vm_intf = dynamic_cast<const VmInterface *>(intf);
1248 :
1249 71 : uint32_t rx_vlan_id = VmInterface::kInvalidVlanId;
1250 71 : VmInterface::VmiType vmi_type = VmInterface::VMI_TYPE_INVALID;
1251 :
1252 71 : if (vm_intf) {
1253 54 : rx_vlan_id = vm_intf->rx_vlan_id();
1254 54 : vmi_type = vm_intf->vmi_type();
1255 : }
1256 :
1257 71 : if (IsValidOsIndex(intf->os_index(), intf->type(), rx_vlan_id,
1258 71 : vmi_type, intf->transport()) == false) {
1259 0 : return DBFilterIgnore;
1260 : }
1261 :
1262 135 : if (intf->type() == Interface::LOGICAL ||
1263 64 : intf->type() == Interface::REMOTE_PHYSICAL) {
1264 7 : return DBFilterIgnore;
1265 : }
1266 :
1267 : // No need to add VLAN sub-interface if there is no parent
1268 64 : if (vm_intf && vm_intf->device_type() == VmInterface::VM_VLAN_ON_VMI &&
1269 0 : vm_intf->parent() == NULL) {
1270 0 : return DBFilterIgnore;
1271 : }
1272 :
1273 64 : return DBFilterAccept;
1274 : }
1275 :
1276 : //////////////////////////////////////////////////////////////////////////////
1277 : // sandesh routines
1278 : //////////////////////////////////////////////////////////////////////////////
1279 1093 : void vr_response::Process(SandeshContext *context) {
1280 1093 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
1281 1093 : ioc->SetErrno(ioc->VrResponseMsgHandler(this));
1282 1093 : }
1283 :
1284 0 : void InterfaceKSyncEntry::SetKsyncItfSandeshData(KSyncItfSandeshData *data) const {
1285 :
1286 0 : data->set_analyzer_name(analyzer_name_);
1287 :
1288 0 : if (drop_new_flows_) {
1289 0 : data->set_drop_new_flows("Enable");
1290 : } else {
1291 0 : data->set_drop_new_flows("Disable");
1292 : }
1293 :
1294 0 : if (dhcp_enable_) {
1295 0 : data->set_dhcp_service("Enable");
1296 : } else {
1297 0 : data->set_dhcp_service("Disable");
1298 : }
1299 :
1300 0 : data->set_fd(fd_);
1301 0 : data->set_flow_key_nh_id(flow_key_nh_id_);
1302 :
1303 0 : if (has_service_vlan_) {
1304 0 : data->set_has_service_vlan("Enable");
1305 : } else {
1306 0 : data->set_has_service_vlan("Disable");
1307 : }
1308 :
1309 0 : data->set_interface_id(interface_id_);
1310 0 : data->set_interface_name(interface_name_);
1311 0 : data->set_ip(ip_);
1312 :
1313 0 : if (hc_active_) {
1314 0 : data->set_health_check("Active");
1315 : } else {
1316 0 : data->set_health_check("Inactive");
1317 : }
1318 :
1319 0 : if (ipv4_active_) {
1320 0 : data->set_ipv4_active("Active");
1321 : } else {
1322 0 : data->set_ipv4_active("Inactive");
1323 : }
1324 :
1325 0 : if (layer3_forwarding_) {
1326 0 : data->set_layer3_forwarding("Enable");
1327 : } else {
1328 0 : data->set_layer3_forwarding("Disable");
1329 : }
1330 :
1331 0 : if (l2_active_) {
1332 0 : data->set_l2_active("Active");
1333 : } else {
1334 0 : data->set_l2_active("Inactive");
1335 : }
1336 :
1337 0 : if (metadata_l2_active_) {
1338 0 : data->set_metadata_l2_active("Active");
1339 : } else {
1340 0 : data->set_metadata_l2_active("Inactive");
1341 : }
1342 :
1343 :
1344 0 : if (metadata_ip_active_) {
1345 0 : data->set_metadata_ip_active("Active");
1346 : } else {
1347 0 : data->set_metadata_ip_active("Inactive");
1348 : }
1349 :
1350 0 : if (bridging_) {
1351 0 : data->set_bridging("Enable");
1352 : } else {
1353 0 : data->set_l2_active("Disable");
1354 : }
1355 :
1356 0 : data->set_mac(mac_.ToString());
1357 0 : data->set_smac(smac_.ToString());
1358 0 : data->set_network_id(network_id_);
1359 0 : data->set_os_index(os_index_);
1360 :
1361 0 : if (policy_enabled_) {
1362 0 : data->set_policy_enabled("Enable");
1363 : } else {
1364 0 : data->set_policy_enabled("Disable");
1365 : }
1366 :
1367 0 : data->set_rx_vlan_id(rx_vlan_id_);
1368 0 : data->set_tx_vlan_id(tx_vlan_id_);
1369 0 : data->set_vrf_id(vrf_id_);
1370 :
1371 0 : if (persistent_) {
1372 0 : data->set_persistent("Enable");
1373 : } else {
1374 0 : data->set_persistent("Disable");
1375 : }
1376 :
1377 0 : if (no_arp_) {
1378 0 : data->set_no_arp("Enable");
1379 : } else {
1380 0 : data->set_no_arp("Disable");
1381 : }
1382 :
1383 0 : data->set_display_name(display_name_);
1384 :
1385 0 : if (flood_unknown_unicast_) {
1386 0 : data->set_flood_unknown_unicast("Enable");
1387 : } else {
1388 0 : data->set_flood_unknown_unicast("Disable");
1389 : }
1390 :
1391 0 : if (learning_enabled_) {
1392 0 : data->set_learning("Enable");
1393 : } else {
1394 0 : data->set_learning("Disable");
1395 : }
1396 :
1397 0 : data->set_isid(isid_);
1398 0 : data->set_pbb_cmac_vrf(pbb_cmac_vrf_);
1399 0 : data->set_pbb_mac(pbb_mac_.ToString());
1400 :
1401 0 : if (etree_leaf_) {
1402 0 : data->set_etree_leaf("Enable");
1403 : } else {
1404 0 : data->set_etree_leaf("Disable");
1405 : }
1406 :
1407 0 : if (pbb_interface_) {
1408 0 : data->set_pbb_interface("Enable");
1409 : } else {
1410 0 : data->set_pbb_interface("Disable");
1411 : }
1412 :
1413 0 : if (igmp_enable_) {
1414 0 : data->set_igmp_enable("Enable");
1415 : } else {
1416 0 : data->set_igmp_enable("Disable");
1417 : }
1418 :
1419 0 : if (mac_ip_learning_enable_) {
1420 0 : data->set_mac_ip_learning_enable("Enable");
1421 : } else {
1422 0 : data->set_mac_ip_learning_enable("Disable");
1423 : }
1424 0 : }
1425 :
1426 0 : bool InterfaceKSyncEntry::KSyncEntrySandesh(Sandesh *sresp) {
1427 0 : KSyncItfResp *resp = static_cast<KSyncItfResp *> (sresp);
1428 :
1429 0 : KSyncItfSandeshData data;
1430 0 : SetKsyncItfSandeshData(&data);
1431 : std::vector<KSyncItfSandeshData> &list =
1432 0 : const_cast<std::vector<KSyncItfSandeshData>&>(resp->get_KSyncitf_list());
1433 0 : list.push_back(data);
1434 :
1435 0 : return true;
1436 0 : }
1437 :
1438 0 : void KSyncItfReq::HandleRequest() const {
1439 0 : AgentKsyncSandeshPtr sand(new AgentKsyncIntfSandesh(context()));
1440 0 : sand->DoKsyncSandesh(sand);
1441 :
1442 0 : }
|