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