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 45 : InterfaceKSyncEntry::InterfaceKSyncEntry(InterfaceKSyncObject *obj,
46 : const InterfaceKSyncEntry *entry,
47 45 : uint32_t index) :
48 45 : KSyncNetlinkDBEntry(index), analyzer_name_(entry->analyzer_name_),
49 45 : drop_new_flows_(entry->drop_new_flows_),
50 45 : dhcp_enable_(entry->dhcp_enable_),
51 45 : dhcp_enable_v6_(entry->dhcp_enable_v6_),
52 45 : fd_(kInvalidIndex),
53 45 : flow_key_nh_id_(entry->flow_key_nh_id_),
54 45 : has_service_vlan_(entry->has_service_vlan_),
55 45 : interface_id_(entry->interface_id_),
56 45 : interface_name_(entry->interface_name_),
57 45 : ip_(entry->ip_), primary_ip6_(entry->primary_ip6_),
58 45 : hc_active_(false), ipv4_active_(false),
59 45 : layer3_forwarding_(entry->layer3_forwarding_),
60 45 : ksync_obj_(obj), l2_active_(false),
61 45 : metadata_l2_active_(entry->metadata_l2_active_),
62 45 : metadata_ip_active_(entry->metadata_ip_active_),
63 45 : bridging_(entry->bridging_),
64 45 : proxy_arp_mode_(VmInterface::PROXY_ARP_NONE),
65 45 : mac_(entry->mac_),
66 45 : smac_(entry->smac_),
67 45 : mirror_direction_(entry->mirror_direction_),
68 45 : network_id_(entry->network_id_),
69 45 : os_index_(Interface::kInvalidIndex),
70 45 : parent_(entry->parent_),
71 45 : policy_enabled_(entry->policy_enabled_),
72 45 : sub_type_(entry->sub_type_),
73 45 : vmi_device_type_(entry->vmi_device_type_),
74 45 : vmi_type_(entry->vmi_type_),
75 45 : hbs_intf_type_(entry->hbs_intf_type_),
76 45 : type_(entry->type_),
77 45 : rx_vlan_id_(entry->rx_vlan_id_),
78 45 : tx_vlan_id_(entry->tx_vlan_id_),
79 45 : vrf_id_(entry->vrf_id_),
80 45 : multicast_vrf_id_(entry->multicast_vrf_id_),
81 45 : persistent_(entry->persistent_),
82 45 : subtype_(entry->subtype_),
83 45 : xconnect_(entry->xconnect_),
84 45 : no_arp_(entry->no_arp_),
85 45 : encap_type_(entry->encap_type_),
86 45 : display_name_(entry->display_name_),
87 45 : transport_(entry->transport_),
88 45 : flood_unknown_unicast_ (entry->flood_unknown_unicast_),
89 45 : qos_config_(entry->qos_config_),
90 45 : learning_enabled_(entry->learning_enabled_),
91 45 : isid_(entry->isid_), pbb_cmac_vrf_(entry->pbb_cmac_vrf_),
92 45 : pbb_mac_(entry->pbb_mac_), etree_leaf_(entry->etree_leaf_),
93 45 : pbb_interface_(entry->pbb_interface_),
94 45 : vhostuser_mode_(entry->vhostuser_mode_),
95 45 : igmp_enable_(entry->igmp_enable_),
96 45 : mac_ip_learning_enable_(false),
97 45 : os_guid_(entry->os_guid_),
98 135 : xconnect_list_(entry->xconnect_list_) {
99 45 : }
100 :
101 1836 : InterfaceKSyncEntry::InterfaceKSyncEntry(InterfaceKSyncObject *obj,
102 1836 : const Interface *intf) :
103 : KSyncNetlinkDBEntry(kInvalidIndex),
104 1836 : analyzer_name_(),
105 1836 : drop_new_flows_(false),
106 1836 : dhcp_enable_(true),
107 1836 : dhcp_enable_v6_(false),
108 1836 : fd_(-1),
109 1836 : flow_key_nh_id_(0),
110 1836 : has_service_vlan_(false),
111 1836 : interface_id_(intf->id()),
112 1836 : interface_name_(intf->name()),
113 1836 : ip_(0),
114 1836 : hc_active_(false),
115 1836 : ipv4_active_(false),
116 1836 : layer3_forwarding_(true),
117 1836 : ksync_obj_(obj),
118 1836 : l2_active_(false),
119 1836 : metadata_l2_active_(false),
120 1836 : metadata_ip_active_(false),
121 1836 : bridging_(true),
122 1836 : proxy_arp_mode_(VmInterface::PROXY_ARP_NONE),
123 1836 : mac_(),
124 1836 : smac_(),
125 1836 : mirror_direction_(Interface::UNKNOWN),
126 1836 : os_index_(intf->os_index()),
127 1836 : parent_(NULL),
128 1836 : policy_enabled_(false),
129 1836 : sub_type_(InetInterface::VHOST),
130 1836 : vmi_device_type_(VmInterface::DEVICE_TYPE_INVALID),
131 1836 : vmi_type_(VmInterface::VMI_TYPE_INVALID),
132 1836 : hbs_intf_type_(VmInterface::HBS_INTF_INVALID),
133 1836 : type_(intf->type()),
134 1836 : rx_vlan_id_(VmInterface::kInvalidVlanId),
135 1836 : tx_vlan_id_(VmInterface::kInvalidVlanId),
136 1836 : vrf_id_(intf->vrf_id()),
137 1836 : multicast_vrf_id_(VrfEntry::kInvalidIndex),
138 1836 : persistent_(false),
139 1836 : subtype_(PhysicalInterface::INVALID),
140 1836 : xconnect_(NULL),
141 1836 : no_arp_(false),
142 1836 : encap_type_(PhysicalInterface::ETHERNET),
143 1836 : transport_(Interface::TRANSPORT_INVALID),
144 1836 : flood_unknown_unicast_(false), qos_config_(NULL),
145 1836 : learning_enabled_(false), isid_(VmInterface::kInvalidIsid),
146 1836 : pbb_cmac_vrf_(VrfEntry::kInvalidIndex), pbb_mac_(), etree_leaf_(false),
147 1836 : pbb_interface_(false), vhostuser_mode_(VmInterface::vHostUserClient),
148 1836 : igmp_enable_(false), mac_ip_learning_enable_(false),
149 1836 : os_guid_(intf->os_guid()),
150 7344 : xconnect_list_() {
151 :
152 1836 : if (intf->flow_key_nh()) {
153 1676 : flow_key_nh_id_ = intf->flow_key_nh()->id();
154 : }
155 1836 : network_id_ = 0;
156 1836 : if (type_ == Interface::VM_INTERFACE) {
157 1477 : const VmInterface *vmitf =
158 : static_cast<const VmInterface *>(intf);
159 1477 : ip_ = vmitf->primary_ip_addr().to_ulong();
160 1477 : primary_ip6_ = vmitf->primary_ip6_addr();
161 1477 : network_id_ = vmitf->vxlan_id();
162 1477 : rx_vlan_id_ = vmitf->rx_vlan_id();
163 1477 : tx_vlan_id_ = vmitf->tx_vlan_id();
164 1477 : vhostuser_mode_ = vmitf->vhostuser_mode();
165 1477 : if (vmitf->parent()) {
166 109 : InterfaceKSyncEntry tmp(ksync_obj_, vmitf->parent());
167 109 : parent_ = ksync_obj_->GetReference(&tmp);
168 109 : }
169 1477 : vmi_device_type_ = vmitf->device_type();
170 1477 : vmi_type_ = vmitf->vmi_type();
171 1477 : if (vmi_type_ == VmInterface::VHOST) {
172 218 : for (size_t i = 0; i <vmitf->parent_list().size(); i++) {
173 109 : InterfaceKSyncEntry tmp(ksync_obj_, vmitf->parent_list()[i]);
174 109 : xconnect_list_.push_back(ksync_obj_->GetReference(&tmp));
175 109 : }
176 109 : parent_ = NULL;
177 : InterfaceKSyncEntry *xconnect = static_cast<InterfaceKSyncEntry *>
178 109 : (xconnect_list_[0].get());
179 109 : encap_type_ = xconnect->encap_type();
180 109 : no_arp_ = xconnect->no_arp();
181 : }
182 1477 : hbs_intf_type_ = vmitf->hbs_intf_type();
183 359 : } 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 359 : } else if (type_ == Interface::PHYSICAL) {
197 233 : const PhysicalInterface *physical_intf =
198 : static_cast<const PhysicalInterface *>(intf);
199 233 : encap_type_ = physical_intf->encap_type();
200 233 : no_arp_ = physical_intf->no_arp();
201 233 : display_name_ = physical_intf->display_name();
202 233 : ip_ = physical_intf->ip_addr().to_ulong();
203 : }
204 1836 : }
205 :
206 1971 : InterfaceKSyncEntry::~InterfaceKSyncEntry() {
207 1971 : }
208 :
209 932 : KSyncDBObject *InterfaceKSyncEntry::GetObject() const {
210 932 : return ksync_obj_;
211 : }
212 :
213 7466 : bool InterfaceKSyncEntry::IsLess(const KSyncEntry &rhs) const {
214 7466 : const InterfaceKSyncEntry &entry = static_cast
215 : <const InterfaceKSyncEntry &>(rhs);
216 7466 : if (interface_name_ != entry.interface_name_ ) {
217 3789 : return interface_name_ < entry.interface_name_;
218 : } else {
219 3677 : return interface_id_ < entry.interface_id_;
220 : }
221 : }
222 :
223 5623 : std::string InterfaceKSyncEntry::ToString() const {
224 5623 : std::stringstream s;
225 5623 : s << "Interface : " << interface_name_ << " Index : " << interface_id_;
226 : const VrfEntry* vrf =
227 5623 : ksync_obj_->ksync()->agent()->vrf_table()->FindVrfFromId(vrf_id_);
228 5623 : if (vrf) {
229 4361 : s << " Vrf : " << vrf->GetName();
230 : }
231 11246 : return s.str();
232 5623 : }
233 :
234 181 : bool InterfaceKSyncEntry::Sync(DBEntry *e) {
235 181 : Interface *intf = static_cast<Interface *>(e);
236 181 : bool ret = false;
237 :
238 181 : if (hc_active_ != intf->is_hc_active()) {
239 45 : hc_active_ = intf->is_hc_active();
240 45 : ret = true;
241 : }
242 :
243 181 : if (ipv4_active_ != intf->ipv4_active()) {
244 55 : ipv4_active_ = intf->ipv4_active();
245 55 : ret = true;
246 : }
247 :
248 181 : if (l2_active_ != intf->l2_active()) {
249 55 : l2_active_ = intf->l2_active();
250 55 : ret = true;
251 : }
252 :
253 181 : if (os_index_ != intf->os_index()) {
254 43 : os_index_ = intf->os_index();
255 43 : ret = true;
256 : }
257 :
258 181 : if (intf->type() == Interface::VM_INTERFACE) {
259 172 : VmInterface *vm_port = static_cast<VmInterface *>(intf);
260 172 : if (vmi_device_type_ != vm_port->device_type()) {
261 0 : vmi_device_type_ = vm_port->device_type();
262 0 : ret = true;
263 : }
264 :
265 172 : if (vmi_type_ != vm_port->vmi_type()) {
266 10 : vmi_type_ = vm_port->vmi_type();
267 10 : ret = true;
268 : }
269 :
270 172 : 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 172 : 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 172 : if (dhcp_enable_ != vm_port->dhcp_enabled()) {
281 2 : dhcp_enable_ = vm_port->dhcp_enabled();
282 2 : ret = true;
283 : }
284 :
285 172 : if (dhcp_enable_v6_ != vm_port->dhcp_enabled_v6()) {
286 68 : dhcp_enable_v6_ = vm_port->dhcp_enabled_v6();
287 68 : ret = true;
288 : }
289 :
290 172 : 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 172 : if (primary_ip6_ != vm_port->primary_ip6_addr()) {
296 0 : primary_ip6_ = vm_port->primary_ip6_addr();
297 0 : ret = true;
298 : }
299 :
300 172 : if (layer3_forwarding_ != vm_port->layer3_forwarding()) {
301 50 : layer3_forwarding_ = vm_port->layer3_forwarding();
302 50 : ret = true;
303 : }
304 :
305 172 : 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 172 : if (bridging_ != vm_port->bridging()) {
311 81 : bridging_ = vm_port->bridging();
312 81 : ret = true;
313 : }
314 :
315 172 : 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 172 : 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 172 : 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 172 : if (vhostuser_mode_ != vm_port->vhostuser_mode()) {
331 0 : vhostuser_mode_ = vm_port->vhostuser_mode();
332 0 : ret = true;
333 : }
334 :
335 172 : KSyncEntryPtr parent = NULL;
336 172 : if (vm_port->parent()) {
337 5 : InterfaceKSyncEntry tmp(ksync_obj_, vm_port->parent());
338 5 : parent = ksync_obj_->GetReference(&tmp);
339 5 : }
340 :
341 172 : if (parent_ != parent) {
342 5 : parent_ = parent;
343 5 : ret = true;
344 : }
345 :
346 172 : if (metadata_l2_active_ !=
347 172 : vm_port->metadata_l2_active()) {
348 44 : metadata_l2_active_ =
349 44 : vm_port->metadata_l2_active();
350 44 : ret = true;
351 : }
352 :
353 172 : if (metadata_ip_active_ !=
354 172 : vm_port->metadata_ip_active()) {
355 47 : metadata_ip_active_ =
356 47 : vm_port->metadata_ip_active();
357 47 : ret = true;
358 : }
359 :
360 172 : if (learning_enabled_ != vm_port->learning_enabled()) {
361 4 : learning_enabled_ = vm_port->learning_enabled();
362 4 : ret = true;
363 : }
364 :
365 172 : if (pbb_interface_ != vm_port->pbb_interface()) {
366 30 : pbb_interface_ = vm_port->pbb_interface();
367 30 : ret = true;
368 : }
369 :
370 172 : if (l2_active_ && pbb_interface_ && isid_ != vm_port->GetIsid()) {
371 15 : isid_ = vm_port->GetIsid();
372 15 : ret = true;
373 : }
374 :
375 198 : if (l2_active_ && pbb_interface_ &&
376 26 : pbb_cmac_vrf_ != vm_port->GetPbbVrf()) {
377 14 : pbb_cmac_vrf_ = vm_port->GetPbbVrf();
378 14 : ret = true;
379 : }
380 :
381 172 : if (etree_leaf_ != vm_port->etree_leaf()) {
382 10 : etree_leaf_ = vm_port->etree_leaf();
383 10 : ret = true;
384 : }
385 :
386 172 : if (igmp_enable_ != vm_port->igmp_enabled()) {
387 0 : igmp_enable_ = vm_port->igmp_enabled();
388 0 : ret = true;
389 : }
390 :
391 172 : 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 172 : }
396 :
397 181 : uint32_t vrf_id = VIF_VRF_INVALID;
398 181 : uint32_t multicast_vrf_id = VIF_VRF_INVALID;
399 181 : bool policy_enabled = false;
400 181 : std::string analyzer_name;
401 181 : Interface::MirrorDirection mirror_direction = Interface::UNKNOWN;
402 181 : bool has_service_vlan = false;
403 181 : if (l2_active_ || ipv4_active_ || metadata_l2_active_ || metadata_ip_active_) {
404 108 : vrf_id = intf->vrf_id();
405 108 : if (vrf_id == VrfEntry::kInvalidIndex) {
406 3 : vrf_id = VIF_VRF_INVALID;
407 : }
408 :
409 108 : if (intf->type() == Interface::VM_INTERFACE) {
410 99 : VmInterface *vm_port = static_cast<VmInterface *>(intf);
411 99 : if (vm_port->forwarding_vrf()) {
412 99 : vrf_id = vm_port->forwarding_vrf()->vrf_id();
413 : }
414 :
415 99 : if (vmi_type_ != VmInterface::VHOST) {
416 96 : multicast_vrf_id = intf->vrf_id();
417 96 : if (pbb_interface_ && l2_active_) {
418 26 : multicast_vrf_id = vm_port->GetPbbVrf();;
419 : }
420 :
421 96 : if (multicast_vrf_id == VrfEntry::kInvalidIndex) {
422 0 : multicast_vrf_id = VIF_VRF_INVALID;
423 : }
424 : }
425 :
426 99 : has_service_vlan = vm_port->HasServiceVlan();
427 99 : policy_enabled = vm_port->policy_enabled();
428 99 : analyzer_name = vm_port->GetAnalyzer();
429 99 : mirror_direction = vm_port->mirror_direction();
430 99 : if (network_id_ != vm_port->vxlan_id()) {
431 32 : network_id_ = vm_port->vxlan_id();
432 32 : ret = true;
433 : }
434 : }
435 : }
436 :
437 181 : 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 181 : KSyncEntryPtr qos_config = NULL;
463 : QosConfigKSyncObject *qos_object =
464 181 : static_cast<InterfaceKSyncObject *>(ksync_obj_)->ksync()->
465 181 : qos_config_ksync_obj();
466 181 : 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 181 : if (qos_config != qos_config_) {
471 0 : qos_config_ = qos_config;
472 0 : ret = true;
473 : }
474 :
475 181 : if (vrf_id != vrf_id_) {
476 84 : vrf_id_ = vrf_id;
477 84 : ret = true;
478 : }
479 :
480 181 : if (multicast_vrf_id_ != multicast_vrf_id) {
481 119 : multicast_vrf_id_ = multicast_vrf_id;
482 119 : ret = true;
483 : }
484 :
485 181 : if (policy_enabled_ != policy_enabled) {
486 44 : policy_enabled_ = policy_enabled;
487 44 : ret = true;
488 : }
489 :
490 181 : if (analyzer_name_ != analyzer_name) {
491 0 : analyzer_name_ = analyzer_name;
492 0 : ret = true;
493 : }
494 :
495 181 : if (mirror_direction_ != mirror_direction) {
496 0 : mirror_direction_ = mirror_direction;
497 0 : ret = true;
498 : }
499 :
500 181 : if (has_service_vlan_ != has_service_vlan) {
501 0 : has_service_vlan_ = has_service_vlan;
502 0 : ret = true;
503 : }
504 :
505 181 : InterfaceTable *table = static_cast<InterfaceTable *>(intf->get_table());
506 181 : MacAddress dmac;
507 :
508 181 : switch (intf->type()) {
509 172 : case Interface::VM_INTERFACE:
510 : {
511 172 : const VmInterface *vm_intf = static_cast<const VmInterface *>(intf);
512 172 : 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 172 : vm_intf->BuildFatFlowExcludeList(&fat_flow_exclude_list_);
517 172 : std::set<MacAddress> aap_mac_list;
518 172 : for (VmInterface::AllowedAddressPairSet::iterator aap_it =
519 172 : vm_intf->allowed_address_pair_list().list_.begin();
520 172 : 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 172 : if (aap_mac_list_ != aap_mac_list) {
525 0 : aap_mac_list_.swap(aap_mac_list);
526 0 : ret = true;
527 : }
528 172 : MacAddress pbb_mac;
529 172 : if (pbb_interface_) {
530 26 : pbb_mac = MacAddress(vm_intf->vm_mac());
531 : }
532 172 : if (pbb_mac != pbb_mac_) {
533 30 : pbb_mac_ = pbb_mac;
534 30 : ret = true;
535 : }
536 172 : }
537 175 : case Interface::PACKET:
538 175 : dmac = table->agent()->vrrp_mac();
539 175 : break;
540 :
541 6 : case Interface::PHYSICAL:
542 : {
543 6 : dmac = intf->mac();
544 6 : PhysicalInterface *phy_intf = static_cast<PhysicalInterface *>(intf);
545 6 : persistent_ = phy_intf->persistent();
546 6 : subtype_ = phy_intf->subtype();
547 6 : 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 181 : if (dmac != mac()) {
583 47 : mac_ = dmac;
584 47 : ret = true;
585 : }
586 :
587 : // In VMWare VCenter mode, interface is assigned using the SMAC
588 : // in packet. Store the SMAC for interface
589 181 : MacAddress smac;
590 353 : if (intf->type() == Interface::VM_INTERFACE &&
591 344 : (ksync_obj_->ksync()->agent()->isVmwareVcenterMode() ||
592 344 : ksync_obj_->ksync()->agent()->server_gateway_mode() ||
593 172 : 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 181 : 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 181 : uint32_t nh_id = 0;
611 181 : if (intf->flow_key_nh()) {
612 103 : nh_id = intf->flow_key_nh()->id();
613 : }
614 181 : if (nh_id != flow_key_nh_id_) {
615 42 : flow_key_nh_id_ = nh_id;
616 42 : ret = true;
617 : }
618 :
619 181 : if (transport_ != intf->transport()) {
620 43 : transport_ = intf->transport();
621 43 : ret = true;
622 : }
623 :
624 181 : if (os_guid_ != intf->os_guid()) {
625 0 : os_guid_ = intf->os_guid();
626 0 : ret = true;
627 : }
628 :
629 181 : return ret;
630 181 : }
631 :
632 157 : KSyncEntry *InterfaceKSyncEntry::UnresolvedReference() {
633 157 : if (qos_config_.get() && qos_config_->IsResolved() == false) {
634 0 : return qos_config_.get();
635 : }
636 :
637 157 : if (type_ == Interface::INET && sub_type_ == InetInterface::VHOST) {
638 0 : if (xconnect_.get() && !xconnect_->IsResolved()) {
639 0 : return xconnect_.get();
640 : }
641 : }
642 :
643 157 : if (type_ != Interface::VM_INTERFACE) {
644 8 : return NULL;
645 : }
646 :
647 149 : if (parent_.get() && !parent_->IsResolved()) {
648 0 : return parent_.get();
649 : }
650 :
651 149 : 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 149 : return NULL;
663 : }
664 :
665 188 : bool IsValidOsIndex(size_t os_index, Interface::Type type, uint16_t vlan_id,
666 : VmInterface::VmiType vmi_type, Interface::Transport transport) {
667 188 : if (transport != Interface::TRANSPORT_ETHERNET) {
668 11 : return true;
669 : }
670 :
671 177 : if (os_index != Interface::kInvalidIndex)
672 177 : 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 202 : int InterfaceKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) {
688 202 : vr_interface_req encoder;
689 : int encode_len;
690 202 : uint32_t vrf_id = vrf_id_;
691 202 : std::vector<int32_t> cross_connect_idx_list;
692 :
693 202 : uint32_t flags = 0;
694 202 : encoder.set_h_op(op);
695 202 : if (op == sandesh_op::DEL) {
696 45 : encoder.set_vifr_idx(interface_id_);
697 45 : int error = 0;
698 45 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
699 45 : assert(error == 0);
700 45 : assert(encode_len <= buf_len);
701 45 : return encode_len;
702 : }
703 :
704 157 : 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 157 : encoder.set_vifr_qos_map_index(-1);
710 : }
711 :
712 157 : if (etree_leaf_ == false) {
713 148 : flags |= VIF_FLAG_ETREE_ROOT;
714 : }
715 :
716 157 : switch (type_) {
717 149 : case Interface::VM_INTERFACE: {
718 149 : if (vmi_device_type_ == VmInterface::TOR)
719 4 : return 0;
720 145 : if (drop_new_flows_) {
721 0 : flags |= VIF_FLAG_DROP_NEW_FLOWS;
722 : }
723 145 : if (dhcp_enable_ || dhcp_enable_v6_) {
724 141 : flags |= VIF_FLAG_DHCP_ENABLED;
725 : }
726 145 : if (bridging_) {
727 80 : flags |= VIF_FLAG_L2_ENABLED;
728 : }
729 145 : if (vmi_type_ == VmInterface::GATEWAY) {
730 0 : flags |= VIF_FLAG_NO_ARP_PROXY;
731 : }
732 145 : 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 145 : if (flood_unknown_unicast_) {
737 0 : flags |= VIF_FLAG_UNKNOWN_UC_FLOOD;
738 : }
739 145 : if (learning_enabled_) {
740 2 : flags |= VIF_FLAG_MAC_LEARN;
741 : }
742 145 : if (proxy_arp_mode_ == VmInterface::PROXY_ARP_UNRESTRICTED) {
743 0 : flags |= VIF_FLAG_MAC_PROXY;
744 : }
745 145 : if (igmp_enable_) {
746 0 : flags |= VIF_FLAG_IGMP_ENABLED;
747 : }
748 145 : if (mac_ip_learning_enable_) {
749 0 : flags |= VIF_FLAG_MAC_IP_LEARNING;
750 : }
751 145 : MacAddress mac;
752 145 : 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 142 : mac = ksync_obj_->ksync()->agent()->vrrp_mac();
772 142 : encoder.set_vifr_type(VIF_TYPE_VIRTUAL);
773 : }
774 :
775 145 : 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 145 : (int8_t *)mac + mac.size());
792 145 : encoder.set_vifr_mac(intf_mac);
793 :
794 435 : if (ksync_obj_->ksync()->agent()->isVmwareVcenterMode() ||
795 290 : ((ksync_obj_->ksync()->agent()->server_gateway_mode() ||
796 145 : 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 145 : 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 145 : if (pbb_interface_) {
937 : std::vector<int8_t> pbb_mac((int8_t *)pbb_mac_,
938 23 : (int8_t *)pbb_mac_ + mac.size());
939 23 : encoder.set_vifr_pbb_mac(pbb_mac);
940 23 : encoder.set_vifr_isid(isid_);
941 23 : if (pbb_cmac_vrf_ != VrfEntry::kInvalidIndex) {
942 23 : vrf_id = pbb_cmac_vrf_;
943 : }
944 23 : }
945 :
946 145 : 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 145 : encoder.set_vifr_vhostuser_mode(vhostuser_mode_);
953 145 : break;
954 145 : }
955 :
956 5 : case Interface::PHYSICAL: {
957 5 : encoder.set_vifr_type(VIF_TYPE_PHYSICAL);
958 5 : flags |= VIF_FLAG_L3_ENABLED;
959 5 : flags |= VIF_FLAG_L2_ENABLED;
960 5 : if (!persistent_) {
961 4 : flags |= VIF_FLAG_VHOST_PHYS;
962 : }
963 :
964 5 : if (subtype_ == PhysicalInterface::VMWARE ||
965 10 : ksync_obj_->ksync()->agent()->server_gateway_mode() ||
966 5 : ksync_obj_->ksync()->agent()->pbb_gateway_mode()) {
967 0 : flags |= VIF_FLAG_PROMISCOUS;
968 : }
969 5 : if (subtype_ == PhysicalInterface::CONFIG) {
970 1 : flags |= VIF_FLAG_NATIVE_VLAN_TAG;
971 1 : flags |= VIF_FLAG_FAB_GW_MODE;
972 : }
973 5 : encoder.set_vifr_name(display_name_);
974 :
975 5 : AgentParam *params = ksync_obj_->ksync()->agent()->params();
976 5 : std::vector<int16_t> nic_queue_list;
977 5 : for (std::set<uint16_t>::const_iterator it =
978 5 : params->nic_queue_list().begin();
979 5 : it != params->nic_queue_list().end(); it++) {
980 0 : nic_queue_list.push_back(*it);
981 : }
982 5 : encoder.set_vifr_hw_queues(nic_queue_list);
983 5 : break;
984 5 : }
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 153 : if (layer3_forwarding_) {
1025 123 : flags |= VIF_FLAG_L3_ENABLED;
1026 123 : if (policy_enabled_) {
1027 73 : flags |= VIF_FLAG_POLICY_ENABLED;
1028 : }
1029 123 : MirrorKSyncObject* obj = ksync_obj_->ksync()->mirror_ksync_obj();
1030 123 : 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 123 : if (has_service_vlan_) {
1068 0 : flags |= VIF_FLAG_SERVICE_IF;
1069 : }
1070 : }
1071 :
1072 306 : encoder.set_vifr_mac(std::vector<int8_t>((const int8_t *)mac(),
1073 153 : (const int8_t *)mac() + mac().size()));
1074 :
1075 153 : switch(transport_) {
1076 153 : case Interface::TRANSPORT_ETHERNET: {
1077 153 : encoder.set_vifr_transport(VIF_TRANSPORT_ETH);
1078 153 : 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 153 : encoder.set_vifr_flags(flags);
1095 :
1096 153 : encoder.set_vifr_vrf(vrf_id);
1097 153 : encoder.set_vifr_mcast_vrf(multicast_vrf_id_);
1098 153 : encoder.set_vifr_idx(interface_id_);
1099 153 : encoder.set_vifr_rid(0);
1100 153 : encoder.set_vifr_os_idx(os_index_);
1101 153 : encoder.set_vifr_mtu(0);
1102 153 : if (type_ != Interface::PHYSICAL) {
1103 148 : encoder.set_vifr_name(interface_name_);
1104 : }
1105 153 : encoder.set_vifr_ip(htonl(ip_));
1106 153 : encoder.set_vifr_nh_id(flow_key_nh_id_);
1107 :
1108 : // GUIDs are used as interface identifiers on Windows
1109 306 : 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 153 : int error = 0;
1119 153 : encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
1120 153 : if (error != 0) {
1121 0 : LOG(ERROR, "Error <" << error << ">: Failed to encode sandesh buffer");
1122 0 : return 0;
1123 : }
1124 153 : 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 153 : return encode_len;
1130 202 : }
1131 :
1132 202 : void InterfaceKSyncEntry::FillObjectLog(sandesh_op::type op,
1133 : KSyncIntfInfo &info) const {
1134 202 : info.set_name(interface_name_);
1135 202 : info.set_idx(interface_id_);
1136 :
1137 202 : if (op == sandesh_op::ADD) {
1138 157 : info.set_operation("ADD/CHANGE");
1139 : } else {
1140 45 : info.set_operation("DELETE");
1141 : }
1142 :
1143 202 : if (op == sandesh_op::ADD) {
1144 157 : info.set_os_idx(os_index_);
1145 157 : info.set_vrf_id(vrf_id_);
1146 157 : info.set_hc_active(hc_active_);
1147 157 : info.set_l2_active(l2_active_);
1148 157 : info.set_active(ipv4_active_);
1149 157 : info.set_policy_enabled(policy_enabled_);
1150 157 : info.set_service_enabled(has_service_vlan_);
1151 157 : info.set_analyzer_name(analyzer_name_);
1152 :
1153 157 : std::vector<KSyncIntfFatFlowInfo> fat_flows;
1154 157 : for (VmInterface::FatFlowEntrySet::const_iterator it =
1155 320 : 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 157 : info.set_fat_flows(fat_flows);
1164 : info.set_fat_flow_v4_exclude_list
1165 157 : (fat_flow_exclude_list_.fat_flow_v4_exclude_list_);
1166 : info.set_fat_flow_v6_exclude_upper_list
1167 157 : (fat_flow_exclude_list_.fat_flow_v6_exclude_upper_list_);
1168 : info.set_fat_flow_v6_exclude_lower_list
1169 157 : (fat_flow_exclude_list_.fat_flow_v6_exclude_lower_list_);
1170 : info.set_fat_flow_v6_exclude_plen_list
1171 157 : (fat_flow_exclude_list_.fat_flow_v6_exclude_plen_list_);
1172 157 : }
1173 202 : }
1174 :
1175 157 : int InterfaceKSyncEntry::AddMsg(char *buf, int buf_len) {
1176 157 : KSyncIntfInfo info;
1177 :
1178 157 : FillObjectLog(sandesh_op::ADD, info);
1179 157 : KSYNC_TRACE(Intf, GetObject(), info);
1180 314 : return Encode(sandesh_op::ADD, buf, buf_len);
1181 157 : }
1182 :
1183 45 : int InterfaceKSyncEntry::DeleteMsg(char *buf, int buf_len) {
1184 45 : KSyncIntfInfo info;
1185 45 : FillObjectLog(sandesh_op::DEL, info);
1186 45 : KSYNC_TRACE(Intf, GetObject(), info);
1187 90 : return Encode(sandesh_op::DEL, buf, buf_len);
1188 45 : }
1189 :
1190 112 : int InterfaceKSyncEntry::ChangeMsg(char *buf, int buf_len) {
1191 112 : 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 45 : KSyncEntry *InterfaceKSyncObject::Alloc(const KSyncEntry *entry,
1206 : uint32_t index) {
1207 45 : const InterfaceKSyncEntry *intf =
1208 : static_cast<const InterfaceKSyncEntry *>(entry);
1209 45 : InterfaceKSyncEntry *ksync = new InterfaceKSyncEntry(this, intf, index);
1210 45 : return static_cast<KSyncEntry *>(ksync);
1211 : }
1212 :
1213 45 : KSyncEntry *InterfaceKSyncObject::DBToKSyncEntry(const DBEntry *e) {
1214 45 : const Interface *intf = static_cast<const Interface *>(e);
1215 45 : InterfaceKSyncEntry *key = NULL;
1216 :
1217 45 : switch (intf->type()) {
1218 45 : 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 45 : key = new InterfaceKSyncEntry(this, intf);
1225 45 : break;
1226 :
1227 0 : default:
1228 0 : assert(0);
1229 : break;
1230 : }
1231 45 : 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 188 : InterfaceKSyncObject::DBEntryFilter(const DBEntry *entry,
1244 : const KSyncDBEntry *ksync) {
1245 :
1246 188 : const Interface *intf = dynamic_cast<const Interface *>(entry);
1247 188 : const VmInterface *vm_intf = dynamic_cast<const VmInterface *>(intf);
1248 :
1249 188 : uint32_t rx_vlan_id = VmInterface::kInvalidVlanId;
1250 188 : VmInterface::VmiType vmi_type = VmInterface::VMI_TYPE_INVALID;
1251 :
1252 188 : if (vm_intf) {
1253 172 : rx_vlan_id = vm_intf->rx_vlan_id();
1254 172 : vmi_type = vm_intf->vmi_type();
1255 : }
1256 :
1257 188 : if (IsValidOsIndex(intf->os_index(), intf->type(), rx_vlan_id,
1258 188 : vmi_type, intf->transport()) == false) {
1259 0 : return DBFilterIgnore;
1260 : }
1261 :
1262 369 : if (intf->type() == Interface::LOGICAL ||
1263 181 : 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 181 : 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 181 : return DBFilterAccept;
1274 : }
1275 :
1276 : //////////////////////////////////////////////////////////////////////////////
1277 : // sandesh routines
1278 : //////////////////////////////////////////////////////////////////////////////
1279 2607 : void vr_response::Process(SandeshContext *context) {
1280 2607 : AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
1281 2607 : ioc->SetErrno(ioc->VrResponseMsgHandler(this));
1282 2607 : }
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 : }
|