-
Notifications
You must be signed in to change notification settings - Fork 287
/
Copy pathMeta.h
633 lines (485 loc) · 24.3 KB
/
Meta.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
#pragma once
#include "SaiInterface.h"
#include "SaiAttrWrapper.h"
#include "SaiObjectCollection.h"
#include "PortRelatedSet.h"
#include "AttrKeyMap.h"
#include "OidRefCounter.h"
#include "swss/table.h"
#include <vector>
#include <memory>
#include <set>
#define DEFAULT_VLAN_NUMBER 1
#define MINIMUM_VLAN_NUMBER 1
#define MAXIMUM_VLAN_NUMBER 4094
namespace saimeta
{
class Meta:
public sairedis::SaiInterface
{
public:
using sairedis::SaiInterface::set; // name hiding
Meta(
_In_ std::shared_ptr<SaiInterface> impl);
virtual ~Meta() = default;
public:
virtual sai_status_t apiInitialize(
_In_ uint64_t flags,
_In_ const sai_service_method_table_t *service_method_table) override;
virtual sai_status_t apiUninitialize(void) override;
public: // SAI interface overrides
virtual sai_status_t create(
_In_ sai_object_type_t objectType,
_Out_ sai_object_id_t* objectId,
_In_ sai_object_id_t switchId,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list) override;
virtual sai_status_t remove(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId) override;
virtual sai_status_t set(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr) override;
virtual sai_status_t get(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ uint32_t attr_count,
_Inout_ sai_attribute_t *attr_list) override;
public: // QUAD ENTRY and BULK QUAD ENTRY
SAIREDIS_DECLARE_EVERY_ENTRY(SAIREDIS_SAIINTERFACE_DECLARE_QUAD_ENTRY_OVERRIDE);
SAIREDIS_DECLARE_EVERY_BULK_ENTRY(SAIREDIS_SAIINTERFACE_DECLARE_BULK_ENTRY_OVERRIDE);
public: // bulk QUAD oid
virtual sai_status_t bulkCreate(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t switch_id,
_In_ uint32_t object_count,
_In_ const uint32_t *attr_count,
_In_ const sai_attribute_t **attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_object_id_t *object_id,
_Out_ sai_status_t *object_statuses) override;
virtual sai_status_t bulkRemove(
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_id_t *object_id,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses) override;
virtual sai_status_t bulkSet(
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_id_t *object_id,
_In_ const sai_attribute_t *attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses) override;
virtual sai_status_t bulkGet(
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_id_t *object_id,
_In_ const uint32_t *attr_count,
_Inout_ sai_attribute_t **attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses) override;
public: // stats API
virtual sai_status_t getStats(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_Out_ uint64_t *counters) override;
virtual sai_status_t queryStatsCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_Inout_ sai_stat_capability_list_t *stats_capability) override;
virtual sai_status_t queryStatsStCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_Inout_ sai_stat_st_capability_list_t *stats_capability) override;
virtual sai_status_t getStatsExt(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_In_ sai_stats_mode_t mode,
_Out_ uint64_t *counters) override;
virtual sai_status_t clearStats(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids) override;
virtual sai_status_t bulkGetStats(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_key_t *object_key,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_In_ sai_stats_mode_t mode,
_Inout_ sai_status_t *object_statuses,
_Out_ uint64_t *counters) override;
virtual sai_status_t bulkClearStats(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_key_t *object_key,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_In_ sai_stats_mode_t mode,
_Inout_ sai_status_t *object_statuses) override;
public: // non QUAD API
virtual sai_status_t flushFdbEntries(
_In_ sai_object_id_t switchId,
_In_ uint32_t attrCount,
_In_ const sai_attribute_t *attrList) override;
public: // SAI API
virtual sai_status_t objectTypeGetAvailability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_In_ uint32_t attrCount,
_In_ const sai_attribute_t *attrList,
_Out_ uint64_t *count) override;
virtual sai_status_t queryAttributeCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ sai_attr_id_t attr_id,
_Out_ sai_attr_capability_t *capability) override;
virtual sai_status_t queryAttributeEnumValuesCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ sai_attr_id_t attr_id,
_Inout_ sai_s32_list_t *enum_values_capability) override;
virtual sai_object_type_t objectTypeQuery(
_In_ sai_object_id_t objectId) override;
virtual sai_object_id_t switchIdQuery(
_In_ sai_object_id_t objectId) override;
virtual sai_status_t logSet(
_In_ sai_api_t api,
_In_ sai_log_level_t log_level) override;
virtual sai_status_t queryApiVersion(
_Out_ sai_api_version_t *version) override;
public:
void meta_init_db();
bool isEmpty() const;
void dump() const;
public: // notifications
void meta_sai_on_fdb_event(
_In_ uint32_t count,
_In_ const sai_fdb_event_notification_data_t *data);
void meta_sai_on_nat_event(
_In_ uint32_t count,
_In_ const sai_nat_event_notification_data_t *data);
void meta_sai_on_switch_state_change(
_In_ sai_object_id_t switch_id,
_In_ sai_switch_oper_status_t switch_oper_status);
void meta_sai_on_switch_asic_sdk_health_event(
_In_ sai_object_id_t switch_id,
_In_ sai_switch_asic_sdk_health_severity_t severity,
_In_ sai_timespec_t timestamp,
_In_ sai_switch_asic_sdk_health_category_t category,
_In_ sai_switch_health_data_t data,
_In_ const sai_u8_list_t description);
void meta_sai_on_switch_shutdown_request(
_In_ sai_object_id_t switch_id);
void meta_sai_on_port_state_change(
_In_ uint32_t count,
_In_ const sai_port_oper_status_notification_t *data);
void meta_sai_on_queue_pfc_deadlock_notification(
_In_ uint32_t count,
_In_ const sai_queue_deadlock_notification_data_t *data);
void meta_sai_on_bfd_session_state_change(
_In_ uint32_t count,
_In_ const sai_bfd_session_state_notification_t *data);
void meta_sai_on_port_host_tx_ready_change(
_In_ sai_object_id_t port_id,
_In_ sai_object_id_t switch_id,
_In_ sai_port_host_tx_ready_status_t host_tx_ready_status);
void meta_sai_on_twamp_session_event(
_In_ uint32_t count,
_In_ const sai_twamp_session_event_notification_data_t *data);
private: // notifications helpers
void meta_sai_on_fdb_flush_event_consolidated(
_In_ const sai_fdb_event_notification_data_t& data);
void meta_fdb_event_snoop_oid(
_In_ sai_object_id_t oid);
void meta_sai_on_fdb_event_single(
_In_ const sai_fdb_event_notification_data_t& data);
void meta_sai_on_nat_event_single(
_In_ const sai_nat_event_notification_data_t& data);
void meta_sai_on_port_state_change_single(
_In_ const sai_port_oper_status_notification_t& data);
void meta_sai_on_queue_pfc_deadlock_notification_single(
_In_ const sai_queue_deadlock_notification_data_t& data);
void meta_sai_on_bfd_session_state_change_single(
_In_ const sai_bfd_session_state_notification_t& data);
void meta_sai_on_twamp_session_event_single(
_In_ const sai_twamp_session_event_notification_data_t& data);
private: // validation helpers
sai_status_t meta_generic_validation_objlist(
_In_ const sai_attr_metadata_t& md,
_In_ sai_object_id_t switch_id,
_In_ uint32_t count,
_In_ const sai_object_id_t* list);
sai_status_t meta_genetic_validation_list(
_In_ const sai_attr_metadata_t& md,
_In_ uint32_t count,
_In_ const void* list);
sai_status_t meta_generic_validate_non_object_on_create(
_In_ const sai_object_meta_key_t& meta_key,
_In_ sai_object_id_t switch_id);
sai_object_id_t meta_extract_switch_id(
_In_ const sai_object_meta_key_t& meta_key,
_In_ sai_object_id_t switch_id);
std::shared_ptr<SaiAttrWrapper> get_object_previous_attr(
_In_ const sai_object_meta_key_t& metaKey,
_In_ const sai_attr_metadata_t& md);
std::vector<const sai_attr_metadata_t*> get_attributes_metadata(
_In_ sai_object_type_t objecttype);
void meta_generic_validation_post_get_objlist(
_In_ const sai_object_meta_key_t& meta_key,
_In_ const sai_attr_metadata_t& md,
_In_ sai_object_id_t switch_id,
_In_ uint32_t count,
_In_ const sai_object_id_t* list);
public:
static bool is_ipv6_mask_valid(
_In_ const uint8_t* mask);
static bool isPortObjectIdValid(
_In_ sai_object_type_t object_type);
static std::vector<std::string> getValidPortObjectTypes();
private: // unit tests helpers
bool meta_unittests_get_and_erase_set_readonly_flag(
_In_ const sai_attr_metadata_t& md);
public:
/**
* @brief Enable unittest globally.
*
* @param[in] enable If set to true unittests are enabled.
*/
void meta_unittests_enable(
_In_ bool enable);
/**
* @brief Indicates whether unittests are enabled;
*/
bool meta_unittests_enabled();
/**
* @brief Allow to perform SET operation on READ_ONLY attribute only once.
*
* This function relaxes metadata checking on SET operation, it allows to
* perform SET api on READ_ONLY attribute only once on specific object type and
* specific attribute.
*
* Once means that SET operation is only relaxed for the very next SET call on
* that specific object type and attribute id.
*
* Function is explicitly named ONCE, since it will force test developer to not
* forget that SET check is relaxed, and not forget for future unittests.
*
* Function is provided for more flexible testing using virtual switch. Since
* some of the read only attributes maybe very complex to simulate (for example
* resources used by actual asic when adding next hop or next hop group), then
* it's easier to write such unittest:
*
* TestCase:
* 1. meta_unittests_allow_readonly_set_once(x,y);
* 2. object_x_api->set_attribute(object_id, attr, foo); // attr.id == y
* 3. object_x_api->get_attribute(object_id, 1, attr); // attr.id == y
* 4. check if get result is equal to set result.
*
* On real ASIC, even after allowing SET on read only attribute, actual SET
* should fail.
*
* It can be dangerous to set any readonly attribute to different values since
* internal metadata logic maybe using that value and in some cases metadata
* database may get out of sync and cause unexpected results in api calls up to
* application crash.
*
* This function is not thread safe.
*
* @param[in] object_type Object type on which SET will be possible.
* @param[in] attr_id Attribute ID on which SET will be possible.
*
* @return #SAI_STATUS_SUCCESS on success Failure status code on error
*/
sai_status_t meta_unittests_allow_readonly_set_once(
_In_ sai_object_type_t object_type,
_In_ int32_t attr_id);
public: // unittests method helpers
int32_t getObjectReferenceCount(
_In_ sai_object_id_t oid) const;
bool objectExists(
_In_ const sai_object_meta_key_t& mk) const;
private: // port helpers
sai_status_t meta_port_remove_validation(
_In_ const sai_object_meta_key_t& meta_key);
bool meta_is_object_in_default_state(
_In_ sai_object_id_t oid);
void post_port_remove(
_In_ const sai_object_meta_key_t& meta_key);
void meta_post_port_get(
_In_ const sai_object_meta_key_t& meta_key,
_In_ sai_object_id_t switch_id,
_In_ const uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
void meta_add_port_to_related_map(
_In_ sai_object_id_t port_id,
_In_ const sai_object_list_t& list);
public: // validation post QUAD
void meta_generic_validation_post_create(
_In_ const sai_object_meta_key_t& meta_key,
_In_ sai_object_id_t switch_id,
_In_ const uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
void meta_generic_validation_post_remove(
_In_ const sai_object_meta_key_t& meta_key);
void meta_generic_validation_post_set(
_In_ const sai_object_meta_key_t& meta_key,
_In_ const sai_attribute_t *attr);
void meta_generic_validation_post_get(
_In_ const sai_object_meta_key_t& meta_key,
_In_ sai_object_id_t switch_id,
_In_ const uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
private: // validation QUAD
sai_status_t meta_generic_validation_create(
_In_ const sai_object_meta_key_t& meta_key,
_In_ sai_object_id_t switch_id,
_In_ const uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t meta_generic_validation_remove(
_In_ const sai_object_meta_key_t& meta_key);
sai_status_t meta_generic_validation_set(
_In_ const sai_object_meta_key_t& meta_key,
_In_ const sai_attribute_t *attr);
sai_status_t meta_generic_validation_get(
_In_ const sai_object_meta_key_t& meta_key,
_In_ const uint32_t attr_count,
_In_ sai_attribute_t *attr_list);
protected: // stats
sai_status_t meta_validate_stats(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_Out_ uint64_t *counters,
_In_ sai_stats_mode_t mode);
private: // validate OID
sai_status_t meta_sai_validate_oid(
_In_ sai_object_type_t object_type,
_In_ const sai_object_id_t* object_id,
_In_ sai_object_id_t switch_id,
_In_ bool create);
private: // validate ENTRY
sai_status_t meta_sai_validate_fdb_entry(
_In_ const sai_fdb_entry_t* fdb_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_mcast_fdb_entry(
_In_ const sai_mcast_fdb_entry_t* mcast_fdb_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_neighbor_entry(
_In_ const sai_neighbor_entry_t* neighbor_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_route_entry(
_In_ const sai_route_entry_t* route_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_l2mc_entry(
_In_ const sai_l2mc_entry_t* l2mc_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_ipmc_entry(
_In_ const sai_ipmc_entry_t* ipmc_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_nat_entry(
_In_ const sai_nat_entry_t* nat_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_inseg_entry(
_In_ const sai_inseg_entry_t* inseg_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_my_sid_entry(
_In_ const sai_my_sid_entry_t* my_sid_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_direction_lookup_entry(
_In_ const sai_direction_lookup_entry_t* direction_lookup_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_eni_ether_address_map_entry(
_In_ const sai_eni_ether_address_map_entry_t* eni_ether_address_map_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_vip_entry(
_In_ const sai_vip_entry_t* vip_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_inbound_routing_entry(
_In_ const sai_inbound_routing_entry_t* inbound_routing_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_pa_validation_entry(
_In_ const sai_pa_validation_entry_t* pa_validation_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_outbound_routing_entry(
_In_ const sai_outbound_routing_entry_t* outbound_routing_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_outbound_ca_to_pa_entry(
_In_ const sai_outbound_ca_to_pa_entry_t* outbound_ca_to_pa_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_flow_entry(
_In_ const sai_flow_entry_t* flow_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_meter_bucket_entry(
_In_ const sai_meter_bucket_entry_t* meter_bucket_entry,
_In_ bool create,
_In_ bool get = false);
sai_status_t meta_sai_validate_prefix_compression_entry(
_In_ const sai_prefix_compression_entry_t* prefix_compression_entry,
_In_ bool create,
_In_ bool get = false);
public:
/*
* Those functions will be used to recreate virtual switch local metadata state
* after WARM BOOT.
*/
void meta_warm_boot_notify();
void populate(
_In_ const swss::TableDump& dump);
private:
void clean_after_switch_remove(
_In_ sai_object_id_t switchId);
private:
std::shared_ptr<sairedis::SaiInterface> m_implementation;
private: // database objects
/**
* @brief Port related objects set.
*
* Key in map is port OID, and value is set of related objects ids
* like queues, ipgs and scheduler groups.
*
* This map will help to identify objects to be automatically removed
* when port will be removed.
*/
PortRelatedSet m_portRelatedSet;
/*
* Non object ids don't need reference count since they are leafs and can be
* removed at any time.
*/
OidRefCounter m_oids;
SaiObjectCollection m_saiObjectCollection;
AttrKeyMap m_attrKeys;
private: // unittests
std::set<std::string> m_meta_unittests_set_readonly_set;
bool m_unittestsEnabled;
private: // warm boot
bool m_warmBoot;
};
}