/
vm_interface.h
1831 lines (1609 loc) · 70.2 KB
/
vm_interface.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#ifndef vnsw_agent_vm_interface_hpp
#define vnsw_agent_vm_interface_hpp
#include <oper/oper_dhcp_options.h>
#include <oper/audit_list.h>
#include <oper/ecmp_load_balance.h>
/////////////////////////////////////////////////////////////////////////////
// VmInterface is implementation of VM Port interfaces
//
// All modification to an VmInterface is done only thru the DBTable Request
// handling.
//
// The DBTable request can be generated from multiple events.
// Example : Config update, link-state change, port-ipc message etc.
//
// Only two types of DBTable request can create/delete a VmInterface
// - VmInterfaceConfigData :
// This request type is generated from config processing
// Request of this type of mandatory for all interfaces
// - VmInterfaceNovaData :
// This request type is generated from port-ipc messages to agent
// Request of this type are optional
//
// An VmInterface can be of many types. Different type of VmInterfaces with
// corresponding values of DeviceType and VmiType are given below,
//
// DeviceType = VM_ON_TAP, VmiType = INSTANCE
// Typically represents an interface inside a VM/Container.
// Examples:QEMU VM, Containers, Service-Chain interface etc.
// It will have a TAP interface associated with it. The interface be
// created only by port-ipc message. The config message only updates the
// attributes and does not create interface of this type
//
// DeviceType = VM_PHYSICAL_VLAN, VmiType = INTANCE
// This configuration is used in case of VmWare ESXi.
// Each ESXi VM is assigned a VLAN (by nova-compute). The compute node has
// an uplink port that is member of all VLANs. Agent/VRouter can identify
// VmInterface by tuple <uplink-port, vlan>. The uplink port is seen as a
// phyiscal port on compute node
// The agent->hypervisor_mode_ is also set to ESXi in this case
//
// DeviceType = VM_PHYSICAL_MAC, VmiType = INTANCE and
// This configuration is used in VmWare VCenter
// VCenter:
// Contrail uses distributed vswitch to support VCenter. Each VN is
// allocated a PVLAN. The port on compute node is member of primary-vlan
// and VMs are member of secondary-vlans. Packets from all VMs are
// received on primary-vlan on compute node, hence they are classified
// using source-mac address (which is unique to every VM)
// agent->hypervisor_mode_ is set to VCENTER
// DeviceType = LOCAL_DEVICE, VmiType = GATEWAY
// This configuraiton is used in case of Gateway interfaces connected locally
//
// DeviceType = REMOTE_VM_VLAN_ON_VMI, VmiType = REMOTE_VM
// This configuration is used to model an end-point connected on local
// interface
// The VmInterface is classified based on vlan-tag of packet
//
// DeviceType = TOR, VmiType = BAREMETAL
// This configuration is used to model ToR ports managed with OVS
//
// DeviceType = VM_VLAN_ON_VMI, VmiType = INSTANCE
// This configuration is used to model vlan sub-interfaces and
// Nested Containers (both K8S and Mesos)
// Sub-Interfaces:
// Typically, the sub-interfaces are created over other VmInterfaces with
// DeviceType = VM_ON_TAP
// The VmInterface is classified based on vlan-tag
//
// Nested Containers:
// In case of nested-containers, the first level Container ports are
// created as regular tap-interfaces. The second level containers are
// created as MAC-VLAN ports. Since all second level containers share same
// tap-interface, they are classified using vlan-tag
//
// DBRequest Handling
// ------------------
// All DBRequest are handed off to VmInterface module via methods
// VmInterface::Add() and VmInterface::Delete(). VmInterface modules processes
// request in following stages,
// 1. Config Processing
// This stage is responsible to update VmInterface fields with latest
// information according. The fields updated will depend on type of
// request.
//
// Every DBRequest type implements a method "OnResync". This method must
// update VmInterface fields according to the request
// The same OnResync() is called for both "Add", "Change" and "Resync"
// operation
//
// 2. Apply Config
// This stage is responsible to generated other oper-db states including
// MPLS Labels, NextHops, Routes etc... based on the latest configuration
// It must also take care of removing derived states based on old-state
//
// VmInterfaceState() class is responsible to manage derived states
// such as routes, nexthops, labels etc...).
// old states and create new states based on latest interface configuration
/////////////////////////////////////////////////////////////////////////////
typedef std::vector<boost::uuids::uuid> SgUuidList;
typedef std::vector<SgEntryRef> SgList;
typedef std::vector<AclDBEntryConstRef> FirewallPolicyList;
struct VmInterfaceData;
struct VmInterfaceConfigData;
struct VmInterfaceNovaData;
struct VmInterfaceIpAddressData;
struct VmInterfaceOsOperStateData;
struct VmInterfaceMirrorData;
class OperDhcpOptions;
class PathPreference;
class MetaDataIp;
class HealthCheckInstanceBase;
class LocalVmPortPeer;
class VmInterface;
/////////////////////////////////////////////////////////////////////////////
// VmInterfaceState manages dervied states from VmInterface. On any config
// change to interface, this VmInterfaceState gets invoked after modifying
// VmInterface with latest configuration. Each VmInterfaceState must be
// self-contained and idempotent. The class must store old variables it needs.
//
// There are 2 type of states managed by the class L2-State (EVPN-Route,
// L2-NextHop etc..) and L3-State(inet-route, l3-nexthop etc...). The class
// assumes each both L2 and L3 states are managed by each attribute. However,
// one of them can be dummy as necessary
//
// The class supports 3 different operations,
// - ADD : Must Add state resulting from this attribute
// - DEL : Must Delete state resulting from this attribute
// - DEL_ADD :
// DEL_ADD operation results if there is change in key for the state
// resulting from the attribute. In this case, the old state must be
// Delete and then followed by Addd of state
//
// Guildelines for GetOpL2 and GetOpL3:
// - Compute DEL cases
// - Compute DEL_ADD cases next
// - Compute ADD cases last
// - Return INVALID to ignore the operation
//
// The DEL operation must be based on latest configuration on interface
// The ADD operation must be based on latest configuration on interface
// The DEL_ADD operation must be based on old values stored in the class and
// latest value in the interface
/////////////////////////////////////////////////////////////////////////////
struct VmInterfaceState {
// Keep order of Operation in enum sorted. RecomputeOp relies on it
enum Op {
INVALID,
ADD,
DEL_ADD,
DEL
};
explicit VmInterfaceState() :
l2_installed_(false), l3_installed_(false) {
}
VmInterfaceState(bool l2_installed, bool l3_installed) :
l2_installed_(l2_installed), l3_installed_(l3_installed) {
}
virtual ~VmInterfaceState() {
}
bool Installed() const {
return l3_installed_ || l2_installed_;
}
virtual bool Update(const Agent *agent, VmInterface *vmi,
Op l2_force_op, Op l3_force_op) const;
// Update Operation. In cases where operations are computed in stages,
// computes operation based on old value and new value
static Op RecomputeOp(Op old_op, Op new_op);
// Get operation for Layer-2 state. Generally,
// ADD/DEL operaton are based on current state of VmInterface
// ADD_DEL operation is based on old-value and new value in VmInterface
virtual Op GetOpL2(const Agent *agent, const VmInterface *vmi) const {
return INVALID;
}
// Get operation for Layer-3 state. Generally,
// ADD/DEL operaton are based on current state of VmInterface
// ADD_DEL operation is based on old-value and new value in VmInterface
virtual Op GetOpL3(const Agent *agent, const VmInterface *vmi) const {
return INVALID;
}
// Copy attributes from VmInterface to local copy
virtual void Copy(const Agent *agent, const VmInterface *vmi) const {
return;
}
virtual bool AddL2(const Agent *agent, VmInterface *vmi) const {
assert(0);
return false;
}
virtual bool DeleteL2(const Agent *agent, VmInterface *vmi) const {
assert(0);
return false;
}
virtual bool AddL3(const Agent *agent, VmInterface *vmi) const {
assert(0);
return false;
}
virtual bool DeleteL3(const Agent *agent, VmInterface *vmi) const {
assert(0);
return false;
}
mutable bool l2_installed_;
mutable bool l3_installed_;
};
struct MacVmBindingState : public VmInterfaceState {
MacVmBindingState();
virtual ~MacVmBindingState();
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
mutable const VrfEntry *vrf_;
mutable bool dhcp_enabled_;
};
struct VrfTableLabelState : public VmInterfaceState {
VrfTableLabelState();
virtual ~VrfTableLabelState();
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
};
struct NextHopState : public VmInterfaceState {
NextHopState();
virtual ~NextHopState();
VmInterfaceState::Op GetOpL2(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL2(const Agent *agent, VmInterface *vmi) const;
bool AddL2(const Agent *agent, VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
uint32_t l2_label() const { return l2_label_; }
uint32_t l3_label() const { return l3_label_; }
mutable NextHopRef l2_nh_policy_;
mutable NextHopRef l2_nh_no_policy_;
mutable uint32_t l2_label_;
mutable NextHopRef l3_nh_policy_;
mutable NextHopRef l3_nh_no_policy_;
mutable uint32_t l3_label_;
mutable NextHopRef l3_mcast_nh_no_policy_;
mutable NextHopRef receive_nh_;
};
struct MetaDataIpState : public VmInterfaceState {
MetaDataIpState();
virtual ~MetaDataIpState();
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
mutable std::auto_ptr<MetaDataIp> mdata_ip_;
};
struct ResolveRouteState : public VmInterfaceState {
ResolveRouteState();
virtual ~ResolveRouteState();
VmInterfaceState::Op GetOpL2(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL2(const Agent *agent, VmInterface *vmi) const;
bool AddL2(const Agent *agent, VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
mutable const VrfEntry *vrf_;
mutable Ip4Address subnet_;
mutable uint8_t plen_;
};
struct VmiRouteState : public VmInterfaceState {
VmiRouteState();
virtual ~VmiRouteState();
VmInterfaceState::Op GetOpL2(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL2(const Agent *agent, VmInterface *vmi) const;
bool AddL2(const Agent *agent, VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
mutable const VrfEntry *vrf_;
mutable Ip4Address ip_;
mutable uint32_t ethernet_tag_;
mutable bool do_dhcp_relay_;
};
/////////////////////////////////////////////////////////////////////////////
// Definition for VmInterface
// Agent supports multiple type of VMInterfaces
// - VMI for a virtual-machine spawned on KVM compute node. It will have a TAP
// interface associated with it. Agent also expects a INSTANCE_MSG from
// nova-compute/equivalent to add this port
// DeviceType = VM_ON_TAP, VmiType = INSTANCE
// - VMI for a virtual-machine spawned on VMware ESXi. All virtual-machines
// are connected on a physical-port and VLAN is used to distinguish them
// DeviceType = VM_PHYSICAL_VLAN, VmiType = INTANCE, agent->hypervisor_mode = ESXi
// - VMI for a virtual-machine spawned on VMWare VCenter . All virtual-machines
// are connected on a physical-port and they are classified by the smac
// DeviceType = VM_PHYSICAL_MAC, VmiType = INTANCE and
// agent hypervisor mode = VCenter
// - VMI for service-chain virtual-machines
// - VMI for service-chain virtual-machine spawned on KVM compute node.
// It will have a TAP interface associated with it. Agent also expects a
// INSTANCE_MSG from interface associated with it.
// DeviceType = VM_ON_TAP, VmiType = SERVICE_CHAIN
// - VMI for service-instances spawned by agent itself.
// It will have a TAP interface associated with it. Agent also expects a
// INSTANCE_MSG from interface associated with it.
// DeviceType = VM, VmiType = SERVICE_INTANCE
//
/////////////////////////////////////////////////////////////////////////////
class VmInterface : public Interface {
public:
static const uint32_t kInvalidVlanId = 0xFFFF;
static const uint32_t kInvalidPmdId = 0xFFFF;
static const uint32_t kInvalidIsid = 0xFFFFFF;
static const uint8_t vHostUserClient = 0;
static const uint8_t vHostUserServer = 1;
// Interface route type
static const char *kInterface;
static const char *kServiceInterface;
static const char *kInterfaceStatic;
enum Configurer {
INSTANCE_MSG,
CONFIG
};
// Type of VMI Port
enum DeviceType {
DEVICE_TYPE_INVALID,
VM_ON_TAP, // VMI on TAP/physial port interface
// VMI is created based on the INSTANCE_MSG
VM_VLAN_ON_VMI, // VMI on TAP port with VLAN as classifier
// VMI is created based on config message
VM_PHYSICAL_VLAN, // VMI classified with VLAN on a physical-port
// (used in VMWare ESXi)
// VMI is created based on the INSTANCE_MSG
VM_PHYSICAL_MAC, // VMI classified with MAC on a physical-port
// (used in VMWare VCenter)
// VMI is created based on the INSTANCE_MSG
TOR, // Baremetal connected to ToR
LOCAL_DEVICE, // VMI on a local port. Used in GATEWAY
REMOTE_VM_VLAN_ON_VMI, // VMI on a local phy-port with VLAN as classifier
VM_SRIOV, // VMI on an SRIOV VM
VMI_ON_LR // VMI configured on logical-router
};
// Type of VM on the VMI
enum VmiType {
VMI_TYPE_INVALID,
INSTANCE,
SERVICE_CHAIN,
SERVICE_INSTANCE,
BAREMETAL,
GATEWAY,
REMOTE_VM,
SRIOV,
VHOST,
ROUTER
};
// Interface uses different type of labels. Enumeration of different
// types is given below
enum LabelType {
LABEL_TYPE_INVALID = 0,
LABEL_TYPE_L2,
LABEL_TYPE_L3,
LABEL_TYPE_AAP,
LABEL_TYPE_SERVICE_VLAN,
LABEL_TYPE_MAX
};
enum ProxyArpMode {
PROXY_ARP_NONE,
PROXY_ARP_UNRESTRICTED,
PROXY_ARP_INVALID
};
enum FatFlowIgnoreAddressType {
IGNORE_NONE,
IGNORE_SOURCE,
IGNORE_DESTINATION
};
typedef std::map<Ip4Address, MetaDataIp*> MetaDataIpMap;
typedef std::set<HealthCheckInstanceBase *> HealthCheckInstanceSet;
struct List {
};
struct ListEntry {
ListEntry() : del_pending_(false) { }
ListEntry(bool del_pending) : del_pending_(del_pending) { }
virtual ~ListEntry() {}
bool del_pending() const { return del_pending_; }
void set_del_pending(bool val) const { del_pending_ = val; }
VmInterfaceState::Op GetOp(VmInterfaceState::Op op) const;
mutable bool del_pending_;
};
struct FloatingIpList;
// A unified structure for storing FloatingIp information for both
// operational and config elements
struct FloatingIp : public ListEntry, VmInterfaceState {
enum Direction {
DIRECTION_BOTH,
DIRECTION_INGRESS,
DIRECTION_EGRESS,
DIRECTION_INVALID
};
struct PortMapKey {
uint8_t protocol_;
uint16_t port_;
PortMapKey(): protocol_(0), port_(0) { }
PortMapKey(uint8_t protocol, uint16_t port) :
protocol_(protocol), port_(port) { }
~PortMapKey() { }
bool operator()(const PortMapKey &lhs, const PortMapKey &rhs) const {
if (lhs.protocol_ != rhs.protocol_)
return lhs.protocol_ < rhs.protocol_;
return lhs.port_ < rhs.port_;
}
};
typedef std::map<PortMapKey, uint16_t, PortMapKey> PortMap;
typedef PortMap::iterator PortMapIterator;
FloatingIp();
FloatingIp(const FloatingIp &rhs);
FloatingIp(const IpAddress &addr, const std::string &vrf,
const boost::uuids::uuid &vn_uuid, const IpAddress &ip,
Direction direction, bool port_mappng_enabled,
const PortMap &src_port_map, const PortMap &dst_port_map,
bool port_nat);
virtual ~FloatingIp();
bool operator() (const FloatingIp &lhs, const FloatingIp &rhs) const;
bool IsLess(const FloatingIp *rhs) const;
bool port_map_enabled() const;
Direction direction() const { return direction_; }
const IpAddress GetFixedIp(const VmInterface *) const;
uint32_t PortMappingSize() const;
int32_t GetSrcPortMap(uint8_t protocol, uint16_t src_port) const;
int32_t GetDstPortMap(uint8_t protocol, uint16_t dst_port) const;
// direction_ is based on packet direction. Allow DNAT if direction is
// "both or ingress"
bool AllowDNat() const {
return (direction_ == DIRECTION_BOTH ||
direction_ == DIRECTION_INGRESS);
}
// direction_ is based on packet direction. Allow SNAT if direction is
// "both or egress"
bool AllowSNat() const {
return (direction_ == DIRECTION_BOTH ||
direction_ == DIRECTION_EGRESS);
}
void Copy(const Agent *agent, const VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
VmInterfaceState::Op GetOpL2(const Agent *agent,
const VmInterface *vmi) const;
bool AddL2(const Agent *agent, VmInterface *vmi) const;
bool DeleteL2(const Agent *agent, VmInterface *vmi) const;
bool port_nat() const;
IpAddress floating_ip_;
mutable VnEntryRef vn_;
mutable VrfEntryRef vrf_;
std::string vrf_name_;
boost::uuids::uuid vn_uuid_;
mutable IpAddress fixed_ip_;
mutable Direction direction_;
mutable bool port_map_enabled_;
mutable PortMap src_port_map_;
mutable PortMap dst_port_map_;
mutable uint32_t ethernet_tag_;
mutable bool port_nat_;
};
typedef std::set<FloatingIp, FloatingIp> FloatingIpSet;
struct FloatingIpList : public List {
FloatingIpList() :
List(), v4_count_(0), v6_count_(0), list_() {
}
~FloatingIpList() { }
void Insert(const FloatingIp *rhs);
void Update(const FloatingIp *lhs, const FloatingIp *rhs);
void Remove(FloatingIpSet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
uint16_t v4_count_;
uint16_t v6_count_;
FloatingIpSet list_;
};
// A unified structure for storing AliasIp information for both
// operational and config elements
struct AliasIpList;
struct AliasIp : public ListEntry, VmInterfaceState {
AliasIp();
AliasIp(const AliasIp &rhs);
AliasIp(const IpAddress &addr, const std::string &vrf,
const boost::uuids::uuid &vn_uuid);
virtual ~AliasIp();
bool operator() (const AliasIp &lhs, const AliasIp &rhs) const;
bool IsLess(const AliasIp *rhs) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
IpAddress alias_ip_;
mutable VnEntryRef vn_;
mutable VrfEntryRef vrf_;
std::string vrf_name_;
boost::uuids::uuid vn_uuid_;
};
typedef std::set<AliasIp, AliasIp> AliasIpSet;
struct AliasIpList : public List {
AliasIpList() : v4_count_(0), v6_count_(0), list_() { }
~AliasIpList() { }
void Insert(const AliasIp *rhs);
void Update(const AliasIp *lhs, const AliasIp *rhs);
void Remove(AliasIpSet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
uint16_t v4_count_;
uint16_t v6_count_;
AliasIpSet list_;
};
struct ServiceVlan : ListEntry {
ServiceVlan();
ServiceVlan(const ServiceVlan &rhs);
ServiceVlan(uint16_t tag, const std::string &vrf_name,
const Ip4Address &addr, const Ip6Address &addr6,
const MacAddress &smac, const MacAddress &dmac);
virtual ~ServiceVlan();
bool operator() (const ServiceVlan &lhs, const ServiceVlan &rhs) const;
bool IsLess(const ServiceVlan *rhs) const;
void Update(const Agent *agent, VmInterface *vmi) const;
void DeleteCommon(const VmInterface *vmi) const;
void AddCommon(const Agent *agent, const VmInterface *vmi) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
uint16_t tag_;
mutable std::string vrf_name_;
mutable Ip4Address addr_;
mutable Ip4Address old_addr_;
mutable Ip6Address addr6_;
mutable Ip6Address old_addr6_;
mutable MacAddress smac_;
mutable MacAddress dmac_;
mutable VrfEntryRef vrf_;
mutable uint32_t label_;
mutable bool v4_rt_installed_;
mutable bool v6_rt_installed_;
mutable bool del_add_;
};
typedef std::set<ServiceVlan, ServiceVlan> ServiceVlanSet;
struct ServiceVlanList : List {
ServiceVlanList() : List(), list_() { }
~ServiceVlanList() { }
void Insert(const ServiceVlan *rhs);
void Update(const ServiceVlan *lhs, const ServiceVlan *rhs);
void Remove(ServiceVlanSet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
ServiceVlanSet list_;
};
struct StaticRoute : ListEntry, VmInterfaceState {
StaticRoute();
StaticRoute(const StaticRoute &rhs);
StaticRoute(const IpAddress &addr, uint32_t plen, const IpAddress &gw,
const CommunityList &communities);
virtual ~StaticRoute();
bool operator() (const StaticRoute &lhs, const StaticRoute &rhs) const;
bool IsLess(const StaticRoute *rhs) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
mutable const VrfEntry *vrf_;
IpAddress addr_;
uint32_t plen_;
IpAddress gw_;
CommunityList communities_;
};
typedef std::set<StaticRoute, StaticRoute> StaticRouteSet;
struct StaticRouteList : List {
StaticRouteList() : List(), list_() { }
~StaticRouteList() { }
void Insert(const StaticRoute *rhs);
void Update(const StaticRoute *lhs, const StaticRoute *rhs);
void Remove(StaticRouteSet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
StaticRouteSet list_;
};
struct AllowedAddressPair : ListEntry, VmInterfaceState {
AllowedAddressPair();
AllowedAddressPair(const AllowedAddressPair &rhs);
AllowedAddressPair(const IpAddress &addr, uint32_t plen, bool ecmp,
const MacAddress &mac);
virtual ~AllowedAddressPair();
bool operator() (const AllowedAddressPair &lhs,
const AllowedAddressPair &rhs) const;
bool operator == (const AllowedAddressPair &rhs) const {
return ((mac_ == rhs.mac_) && (addr_ == rhs.addr_) &&
(plen_ == rhs.plen_));
}
bool IsLess(const AllowedAddressPair *rhs) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
VmInterfaceState::Op GetOpL2(const Agent *agent,
const VmInterface *vmi) const;
bool AddL2(const Agent *agent, VmInterface *vmi) const;
bool DeleteL2(const Agent *agent, VmInterface *vmi) const;
IpAddress addr_;
uint32_t plen_;
mutable bool ecmp_;
MacAddress mac_;
mutable bool ecmp_config_changed_;
mutable IpAddress service_ip_;
mutable uint32_t label_;
mutable NextHopRef policy_enabled_nh_;
mutable NextHopRef policy_disabled_nh_;
mutable VrfEntry *vrf_;
mutable uint32_t ethernet_tag_;
};
typedef std::set<AllowedAddressPair, AllowedAddressPair>
AllowedAddressPairSet;
struct AllowedAddressPairList : public List {
AllowedAddressPairList() : List(), list_() { }
~AllowedAddressPairList() { }
void Insert(const AllowedAddressPair *rhs);
void Update(const AllowedAddressPair *lhs,
const AllowedAddressPair *rhs);
void Remove(AllowedAddressPairSet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
AllowedAddressPairSet list_;
};
struct SecurityGroupEntry : ListEntry, VmInterfaceState {
SecurityGroupEntry();
SecurityGroupEntry(const SecurityGroupEntry &rhs);
SecurityGroupEntry(const boost::uuids::uuid &uuid);
virtual ~SecurityGroupEntry();
bool operator == (const SecurityGroupEntry &rhs) const;
bool operator() (const SecurityGroupEntry &lhs,
const SecurityGroupEntry &rhs) const;
bool IsLess(const SecurityGroupEntry *rhs) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
mutable SgEntryRef sg_;
boost::uuids::uuid uuid_;
};
typedef std::set<SecurityGroupEntry, SecurityGroupEntry>
SecurityGroupEntrySet;
typedef std::vector<boost::uuids::uuid> SecurityGroupUuidList;
struct SecurityGroupEntryList {
SecurityGroupEntryList() : list_() { }
~SecurityGroupEntryList() { }
void Insert(const SecurityGroupEntry *rhs);
void Update(const SecurityGroupEntry *lhs,
const SecurityGroupEntry *rhs);
void Remove(SecurityGroupEntrySet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
SecurityGroupEntrySet list_;
};
struct TagEntry : ListEntry, VmInterfaceState {
TagEntry();
TagEntry(const TagEntry &rhs);
TagEntry(uint32_t tag_type, const boost::uuids::uuid &uuid);
virtual ~TagEntry();
bool operator == (const TagEntry &rhs) const;
bool operator() (const TagEntry &lhs, const TagEntry &rhs) const;
bool IsLess(const TagEntry *rhs) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
mutable TagEntryRef tag_;
uint32_t type_;
mutable boost::uuids::uuid uuid_;
};
typedef std::set<TagEntry, TagEntry> TagEntrySet;
typedef std::vector<boost::uuids::uuid> TagGroupUuidList;
struct TagEntryList {
TagEntryList() : list_() { }
~TagEntryList() { }
void Insert(const TagEntry *rhs);
void Update(const TagEntry *lhs,
const TagEntry *rhs);
void Remove(TagEntrySet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
TagEntrySet list_;
};
struct VrfAssignRule : ListEntry {
VrfAssignRule();
VrfAssignRule(const VrfAssignRule &rhs);
VrfAssignRule(uint32_t id,
const autogen::MatchConditionType &match_condition_,
const std::string &vrf_name, bool ignore_acl);
~VrfAssignRule();
bool operator == (const VrfAssignRule &rhs) const;
bool operator() (const VrfAssignRule &lhs,
const VrfAssignRule &rhs) const;
bool IsLess(const VrfAssignRule *rhs) const;
void Update(const Agent *agent, VmInterface *vmi);
const uint32_t id_;
mutable std::string vrf_name_;
mutable bool ignore_acl_;
mutable autogen::MatchConditionType match_condition_;
};
typedef std::set<VrfAssignRule, VrfAssignRule> VrfAssignRuleSet;
struct VrfAssignRuleList : public List {
VrfAssignRuleList() :
List(), list_(), vrf_assign_acl_(NULL) {
}
~VrfAssignRuleList() { }
void Insert(const VrfAssignRule *rhs);
void Update(const VrfAssignRule *lhs, const VrfAssignRule *rhs);
void Remove(VrfAssignRuleSet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
VrfAssignRuleSet list_;
AclDBEntryRef vrf_assign_acl_;
};
struct InstanceIpList;
struct InstanceIp : ListEntry, VmInterfaceState {
InstanceIp();
InstanceIp(const InstanceIp &rhs);
InstanceIp(const IpAddress &ip, uint8_t plen, bool ecmp,
bool is_primary, bool is_service_ip,
bool is_service_health_check_ip,
bool is_local, const IpAddress &tracking_ip);
~InstanceIp();
bool operator == (const InstanceIp &rhs) const;
bool operator() (const InstanceIp &lhs,
const InstanceIp &rhs) const;
InstanceIp operator = (const InstanceIp &rhs) const {
InstanceIp ret(rhs);
return ret;
}
bool IsLess(const InstanceIp *rhs) const;
void Update(const Agent *agent, VmInterface *vmi,
const VmInterface::InstanceIpList *list) const;
void SetPrefixForAllocUnitIpam(VmInterface *intrface) const;
VmInterfaceState::Op GetOpL3(const Agent *agent,
const VmInterface *vmi) const;
bool AddL3(const Agent *agent, VmInterface *vmi) const;
bool DeleteL3(const Agent *agent, VmInterface *vmi) const;
VmInterfaceState::Op GetOpL2(const Agent *agent,
const VmInterface *vmi) const;
bool AddL2(const Agent *agent, VmInterface *vmi) const;
bool DeleteL2(const Agent *agent, VmInterface *vmi) const;
void Copy(const Agent *agent, const VmInterface *vmi) const;
bool is_force_policy() const {
return is_service_health_check_ip_;
}
bool IsL3Only() const {
return is_service_health_check_ip_;
}
const IpAddress ip_;
mutable uint8_t plen_;
mutable bool ecmp_;
mutable bool is_primary_;
mutable bool is_service_ip_; // used for service chain nexthop
mutable bool is_service_health_check_ip_;
mutable bool is_local_;
mutable IpAddress tracking_ip_;
mutable const VrfEntry *vrf_;
mutable uint32_t ethernet_tag_;
};
typedef std::set<InstanceIp, InstanceIp> InstanceIpSet;
struct InstanceIpList : public List {
InstanceIpList(bool is_ipv4) :
List(), is_ipv4_(is_ipv4), list_() {
}
~InstanceIpList() { }
void Insert(const InstanceIp *rhs);
void Update(const InstanceIp *lhs, const InstanceIp *rhs);
void Remove(InstanceIpSet::iterator &it);
virtual bool UpdateList(const Agent *agent, VmInterface *vmi,
VmInterfaceState::Op l2_force_op,
VmInterfaceState::Op l3_force_op);
bool is_ipv4_;
InstanceIpSet list_;
};
typedef std::map<std::string, FatFlowIgnoreAddressType> IgnoreAddressMap;
struct FatFlowEntry : ListEntry {
FatFlowEntry(): protocol(0), port(0),
ignore_address(IGNORE_NONE) {}
FatFlowEntry(const FatFlowEntry &rhs):
protocol(rhs.protocol), port(rhs.port),
ignore_address(rhs.ignore_address) {}
FatFlowEntry(const uint8_t proto, const uint16_t p) :
protocol(proto), port(p),
ignore_address(IGNORE_NONE) {}
FatFlowEntry(const uint8_t proto, const uint16_t p,
std::string ignore_addr);
virtual ~FatFlowEntry(){}
bool operator == (const FatFlowEntry &rhs) const {
return (rhs.protocol == protocol && rhs.port == port &&
rhs.ignore_address == ignore_address);
}
bool operator() (const FatFlowEntry &lhs,
const FatFlowEntry &rhs) const {
return lhs.IsLess(&rhs);
}
bool IsLess(const FatFlowEntry *rhs) const {
if (protocol != rhs->protocol) {
return protocol < rhs->protocol;
}
return port < rhs->port;
}
uint8_t protocol;
uint16_t port;
mutable FatFlowIgnoreAddressType ignore_address;
};
typedef std::set<FatFlowEntry, FatFlowEntry> FatFlowEntrySet;
struct FatFlowList {
FatFlowList(): list_() {}
~FatFlowList() {}
void Insert(const FatFlowEntry *rhs);
void Update(const FatFlowEntry *lhs, const FatFlowEntry *rhs);
void Remove(FatFlowEntrySet::iterator &it);
bool UpdateList(const Agent *agent, VmInterface *vmi);
FatFlowEntrySet list_;
};
struct BridgeDomain : ListEntry {
BridgeDomain(): uuid_(nil_uuid()), vlan_tag_(0),
bridge_domain_(NULL) {}
BridgeDomain(const BridgeDomain &rhs):
uuid_(rhs.uuid_), vlan_tag_(rhs.vlan_tag_),
bridge_domain_(rhs.bridge_domain_) {}
BridgeDomain(const boost::uuids::uuid &uuid, uint32_t vlan_tag):
uuid_(uuid), vlan_tag_(vlan_tag), bridge_domain_(NULL) {}
virtual ~BridgeDomain(){}
bool operator == (const BridgeDomain &rhs) const {
return (uuid_ == rhs.uuid_);
}
bool operator() (const BridgeDomain &lhs,
const BridgeDomain &rhs) const {
return lhs.IsLess(&rhs);
}
bool IsLess(const BridgeDomain *rhs) const {
return uuid_ < rhs->uuid_;
}
boost::uuids::uuid uuid_;
uint32_t vlan_tag_;
mutable BridgeDomainConstRef bridge_domain_;
};
typedef std::set<BridgeDomain, BridgeDomain> BridgeDomainEntrySet;
struct BridgeDomainList {
BridgeDomainList(): list_() {}
~BridgeDomainList() {}
void Insert(const BridgeDomain *rhs);
void Update(const BridgeDomain *lhs, const BridgeDomain *rhs);
void Remove(BridgeDomainEntrySet::iterator &it);
bool Update(const Agent *agent, VmInterface *vmi);
BridgeDomainEntrySet list_;
};