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