7
7
#include < inttypes.h>
8
8
#include < sstream>
9
9
#include < iostream>
10
+ #include < algorithm>
10
11
11
12
using namespace swss ;
12
13
using namespace std ;
@@ -90,14 +91,15 @@ const vector<sai_hostif_trap_type_t> default_trap_ids = {
90
91
SAI_HOSTIF_TRAP_TYPE_TTL_ERROR
91
92
};
92
93
93
- CoppOrch::CoppOrch (DBConnector *db, string tableName ) :
94
- Orch(db, tableName )
94
+ CoppOrch::CoppOrch (vector<TableConnector> &tableConnectors ) :
95
+ Orch( tableConnectors )
95
96
{
96
97
SWSS_LOG_ENTER ();
97
98
98
99
initDefaultHostIntfTable ();
99
100
initDefaultTrapGroup ();
100
101
initDefaultTrapIds ();
102
+ enable_sflow_trap = false ;
101
103
};
102
104
103
105
void CoppOrch::initDefaultHostIntfTable ()
@@ -191,6 +193,60 @@ void CoppOrch::getTrapIdList(vector<string> &trap_id_name_list, vector<sai_hosti
191
193
}
192
194
}
193
195
196
+ bool CoppOrch::createGenetlinkHostIfTable (vector<string> &trap_id_name_list)
197
+ {
198
+ SWSS_LOG_ENTER ();
199
+
200
+ vector<sai_hostif_trap_type_t > trap_id_list;
201
+
202
+ getTrapIdList (trap_id_name_list, trap_id_list);
203
+
204
+ for (auto trap_id : trap_id_list)
205
+ {
206
+ auto host_tbl_entry = m_trapid_hostif_table_map.find (trap_id);
207
+
208
+ if (host_tbl_entry == m_trapid_hostif_table_map.end ())
209
+ {
210
+ sai_object_id_t trap_group_id = m_syncdTrapIds[trap_id].trap_group_obj ;
211
+ auto hostif_map = m_trap_group_hostif_map.find (trap_group_id);
212
+ if (hostif_map != m_trap_group_hostif_map.end ())
213
+ {
214
+ sai_object_id_t hostif_table_entry = SAI_NULL_OBJECT_ID;
215
+ sai_attribute_t attr;
216
+ vector<sai_attribute_t > sai_host_table_attr;
217
+
218
+ attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_TYPE;
219
+ attr.value .s32 = SAI_HOSTIF_TABLE_ENTRY_TYPE_TRAP_ID;
220
+ sai_host_table_attr.push_back (attr);
221
+
222
+ attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_TRAP_ID;
223
+ attr.value .oid = m_syncdTrapIds[trap_id].trap_obj ;
224
+ sai_host_table_attr.push_back (attr);
225
+
226
+ attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_CHANNEL_TYPE;
227
+ attr.value .s32 = SAI_HOSTIF_TABLE_ENTRY_CHANNEL_TYPE_GENETLINK;
228
+ sai_host_table_attr.push_back (attr);
229
+
230
+ attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_HOST_IF;
231
+ attr.value .oid = hostif_map->second ;
232
+ sai_host_table_attr.push_back (attr);
233
+
234
+ sai_status_t status = sai_hostif_api->create_hostif_table_entry (&hostif_table_entry,
235
+ gSwitchId ,
236
+ (uint32_t )sai_host_table_attr.size (),
237
+ sai_host_table_attr.data ());
238
+ if (status != SAI_STATUS_SUCCESS)
239
+ {
240
+ SWSS_LOG_ERROR (" Failed to create hostif table entry failed, rv %d" , status);
241
+ return false ;
242
+ }
243
+ m_trapid_hostif_table_map[trap_id] = hostif_table_entry;
244
+ }
245
+ }
246
+ }
247
+ return true ;
248
+ }
249
+
194
250
bool CoppOrch::applyAttributesToTrapIds (sai_object_id_t trap_group_id,
195
251
const vector<sai_hostif_trap_type_t > &trap_id_list,
196
252
vector<sai_attribute_t > &trap_id_attribs)
@@ -213,9 +269,9 @@ bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
213
269
SWSS_LOG_ERROR (" Failed to create trap %d, rv:%d" , trap_id, status);
214
270
return false ;
215
271
}
216
- m_syncdTrapIds[trap_id] = trap_group_id;
272
+ m_syncdTrapIds[trap_id].trap_group_obj = trap_group_id;
273
+ m_syncdTrapIds[trap_id].trap_obj = hostif_trap_id;
217
274
}
218
-
219
275
return true ;
220
276
}
221
277
@@ -235,6 +291,7 @@ bool CoppOrch::applyTrapIds(sai_object_id_t trap_group, vector<string> &trap_id_
235
291
return applyAttributesToTrapIds (trap_group, trap_id_list, trap_id_attribs);
236
292
}
237
293
294
+
238
295
bool CoppOrch::removePolicer (string trap_group_name)
239
296
{
240
297
SWSS_LOG_ENTER ();
@@ -321,6 +378,69 @@ bool CoppOrch::createPolicer(string trap_group_name, vector<sai_attribute_t> &po
321
378
return true ;
322
379
}
323
380
381
+ bool CoppOrch::createGenetlinkHostIf (string trap_group_name, vector<sai_attribute_t > &genetlink_attribs)
382
+ {
383
+ SWSS_LOG_ENTER ();
384
+
385
+ sai_object_id_t hostif_id;
386
+ sai_status_t sai_status;
387
+
388
+ sai_status = sai_hostif_api->create_hostif (&hostif_id, gSwitchId ,
389
+ (uint32_t )genetlink_attribs.size (),
390
+ genetlink_attribs.data ());
391
+ if (sai_status != SAI_STATUS_SUCCESS)
392
+ {
393
+ SWSS_LOG_ERROR (" Failed to create genetlink hostif for trap group %s, rc=%d" ,
394
+ trap_group_name.c_str (), sai_status);
395
+ return false ;
396
+ }
397
+
398
+ m_trap_group_hostif_map[m_trap_group_map[trap_group_name]] = hostif_id;
399
+ return true ;
400
+ }
401
+
402
+ bool CoppOrch::removeGenetlinkHostIf (string trap_group_name)
403
+ {
404
+ SWSS_LOG_ENTER ();
405
+
406
+ sai_status_t sai_status;
407
+
408
+ for (auto it : m_syncdTrapIds)
409
+ {
410
+ if (it.second .trap_group_obj == m_trap_group_map[trap_group_name])
411
+ {
412
+ auto hostTableEntry = m_trapid_hostif_table_map.find (it.first );
413
+ if (hostTableEntry != m_trapid_hostif_table_map.end ())
414
+ {
415
+ sai_status = sai_hostif_api->remove_hostif_table_entry (hostTableEntry->second );
416
+ if (sai_status != SAI_STATUS_SUCCESS)
417
+ {
418
+ SWSS_LOG_ERROR (" Failed to delete hostif table entry %ld \
419
+ on trap group %s. rc=%d" , hostTableEntry->second ,
420
+ trap_group_name.c_str (), sai_status);
421
+ return false ;
422
+ }
423
+ m_trapid_hostif_table_map.erase (it.first );
424
+ }
425
+ }
426
+ }
427
+
428
+ auto hostInfo = m_trap_group_hostif_map.find (m_trap_group_map[trap_group_name]);
429
+ if (hostInfo != m_trap_group_hostif_map.end ())
430
+ {
431
+ sai_status = sai_hostif_api->remove_hostif (hostInfo->second );
432
+ if (sai_status != SAI_STATUS_SUCCESS)
433
+ {
434
+ SWSS_LOG_ERROR (" Failed to delete host info %ld on trap group %s. rc=%d" ,
435
+ hostInfo->second , trap_group_name.c_str (), sai_status);
436
+ return false ;
437
+ }
438
+ m_trap_group_hostif_map.erase (m_trap_group_map[trap_group_name]);
439
+ }
440
+
441
+ return true ;
442
+ }
443
+
324
444
task_process_status CoppOrch::processCoppRule (Consumer& consumer)
325
445
{
326
446
SWSS_LOG_ENTER ();
@@ -336,6 +456,7 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
336
456
vector<sai_attribute_t > trap_gr_attribs;
337
457
vector<sai_attribute_t > trap_id_attribs;
338
458
vector<sai_attribute_t > policer_attribs;
459
+ vector<sai_attribute_t > genetlink_attribs;
339
460
340
461
if (op == SET_COMMAND)
341
462
{
@@ -346,6 +467,14 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
346
467
if (fvField (*i) == copp_trap_id_list)
347
468
{
348
469
trap_id_list = tokenize (fvValue (*i), list_item_delimiter);
470
+ auto it = std::find (trap_id_list.begin (), trap_id_list.end (), " sample_packet" );
471
+ if (it != trap_id_list.end ())
472
+ {
473
+ if (!enable_sflow_trap)
474
+ {
475
+ return task_process_status::task_need_retry;
476
+ }
477
+ }
349
478
}
350
479
else if (fvField (*i) == copp_queue_field)
351
480
{
@@ -443,6 +572,25 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
443
572
attr.value .s32 = policer_action;
444
573
policer_attribs.push_back (attr);
445
574
}
575
+ else if (fvField (*i) == copp_genetlink_name)
576
+ {
577
+ attr.id = SAI_HOSTIF_ATTR_TYPE;
578
+ attr.value .s32 = SAI_HOSTIF_TYPE_GENETLINK;
579
+ genetlink_attribs.push_back (attr);
580
+
581
+ attr.id = SAI_HOSTIF_ATTR_NAME;
582
+ strncpy (attr.value .chardata , fvValue (*i).c_str (),
583
+ sizeof (attr.value .chardata ));
584
+ genetlink_attribs.push_back (attr);
585
+
586
+ }
587
+ else if (fvField (*i) == copp_genetlink_mcgrp_name)
588
+ {
589
+ attr.id = SAI_HOSTIF_ATTR_GENETLINK_MCGRP_NAME;
590
+ strncpy (attr.value .chardata , fvValue (*i).c_str (),
591
+ sizeof (attr.value .chardata ));
592
+ genetlink_attribs.push_back (attr);
593
+ }
446
594
else
447
595
{
448
596
SWSS_LOG_ERROR (" Unknown copp field specified:%s\n " , fvField (*i).c_str ());
@@ -519,13 +667,29 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
519
667
return task_process_status::task_failed;
520
668
}
521
669
}
670
+
671
+ if (!genetlink_attribs.empty ())
672
+ {
673
+ if (!createGenetlinkHostIf (trap_group_name, genetlink_attribs))
674
+ {
675
+ return task_process_status::task_failed;
676
+ }
677
+ }
522
678
}
523
679
524
680
/* Apply traps to trap group */
525
681
if (!applyTrapIds (m_trap_group_map[trap_group_name], trap_id_list, trap_id_attribs))
526
682
{
527
683
return task_process_status::task_failed;
528
684
}
685
+
686
+ if (!genetlink_attribs.empty ())
687
+ {
688
+ if (!createGenetlinkHostIfTable (trap_id_list))
689
+ {
690
+ return task_process_status::task_failed;
691
+ }
692
+ }
529
693
}
530
694
else if (op == DEL_COMMAND)
531
695
{
@@ -536,6 +700,12 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
536
700
return task_process_status::task_failed;
537
701
}
538
702
703
+ if (!removeGenetlinkHostIf (trap_group_name))
704
+ {
705
+ SWSS_LOG_ERROR (" Failed to remove hostif from trap group %s" , trap_group_name.c_str ());
706
+ return task_process_status::task_failed;
707
+ }
708
+
539
709
/* Do not remove default trap group */
540
710
if (trap_group_name == default_trap_group)
541
711
{
@@ -547,10 +717,16 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
547
717
vector<sai_hostif_trap_type_t > trap_ids_to_reset;
548
718
for (auto it : m_syncdTrapIds)
549
719
{
550
- if (it.second == m_trap_group_map[trap_group_name])
720
+ if (it.second . trap_group_obj == m_trap_group_map[trap_group_name])
551
721
{
552
722
trap_ids_to_reset.push_back (it.first );
553
723
}
724
+ sai_status = sai_hostif_api->remove_hostif_trap (it.second .trap_obj );
725
+ if (sai_status != SAI_STATUS_SUCCESS)
726
+ {
727
+ SWSS_LOG_ERROR (" Failed to remove trap object %ld" , it.second .trap_obj );
728
+ return task_process_status::task_failed;
729
+ }
554
730
}
555
731
556
732
sai_attribute_t attr;
@@ -588,9 +764,49 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
588
764
return task_process_status::task_success;
589
765
}
590
766
767
+ /* Program Sflow trap once we get sflow enable command */
768
+ void CoppOrch::coppProcessSflow (Consumer &consumer)
769
+ {
770
+ auto it = consumer.m_toSync .begin ();
771
+
772
+ while (it != consumer.m_toSync .end ())
773
+ {
774
+ auto tuple = it->second ;
775
+ string op = kfvOp (tuple);
776
+
777
+ /*
778
+ * Need to handled just 'config sflow enable' command to install the sflow trap group
779
+ * for the first time to ensure support of genetlink attributes. Rest of the fields or
780
+ * disable value or DEL command are not required to be handled
781
+ *
782
+ */
783
+ if (op == SET_COMMAND)
784
+ {
785
+ for (auto i : kfvFieldsValues (tuple))
786
+ {
787
+ if (fvField (i) == " admin_state" )
788
+ {
789
+ if (fvValue (i) == " up" )
790
+ {
791
+ enable_sflow_trap = true ;
792
+ }
793
+ }
794
+ }
795
+ }
796
+ it = consumer.m_toSync .erase (it);
797
+ }
798
+ }
799
+
591
800
void CoppOrch::doTask (Consumer &consumer)
592
801
{
593
802
SWSS_LOG_ENTER ();
803
+ string table_name = consumer.getTableName ();
804
+
805
+ if (table_name == CFG_SFLOW_TABLE_NAME)
806
+ {
807
+ coppProcessSflow (consumer);
808
+ return ;
809
+ }
594
810
595
811
if (!gPortsOrch ->allPortsReady ())
596
812
{
0 commit comments