vslib/VirtualSwitchSaiInterfacePort.cpp (108 lines of code) (raw):
#include "VirtualSwitchSaiInterface.h"
#include "swss/logger.h"
#include "meta/sai_serialize.h"
#include "meta/SaiAttributeList.h"
#include <inttypes.h>
using namespace saivs;
using namespace saimeta;
sai_status_t VirtualSwitchSaiInterface::preSetPort(
_In_ sai_object_id_t port_id,
_In_ const sai_attribute_t *attr)
{
SWSS_LOG_ENTER();
// NOTE: should be used only when tap interface is enabled ?
// Special handling for the sampling attribute modification
if (attr->id == SAI_PORT_ATTR_INGRESS_SAMPLEPACKET_ENABLE)
{
// Get the sample-packet object id
sai_object_id_t samplepacket_oid = attr->value.oid;
// Get the interface name from the port id
std::string if_name;
sai_object_id_t vs_switch_id = switchIdQuery(port_id);
if (vs_switch_id == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_ERROR("vs_switch_id is null");
return SAI_STATUS_FAILURE;
}
auto it = m_switchStateMap.find(vs_switch_id);
if (it == m_switchStateMap.end())
{
SWSS_LOG_ERROR("No switch state found for the switch id %s",
sai_serialize_object_id(vs_switch_id).c_str());
return SAI_STATUS_FAILURE;
}
auto sw = it->second;
if (sw == nullptr)
{
SWSS_LOG_ERROR("switch state for the switch id %s is null",
sai_serialize_object_id(vs_switch_id).c_str());
return SAI_STATUS_FAILURE;
}
if (sw->getTapNameFromPortId(port_id, if_name) == false)
{
SWSS_LOG_ERROR("tap interface name corresponding to the port id %s is not found",
sai_serialize_object_id(port_id).c_str());
return SAI_STATUS_FAILURE;
}
std::string cmd;
if (samplepacket_oid == SAI_NULL_OBJECT_ID)
{
// Delete the sampling session
cmd.assign("tc qdisc delete dev " + if_name + " handle ffff: ingress");
if (system(cmd.c_str()) == -1)
{
SWSS_LOG_ERROR("unable to delete the sampling session for the interface %s", if_name.c_str());
SWSS_LOG_ERROR("failed to apply the command: %s", cmd.c_str());
return SAI_STATUS_FAILURE;
}
SWSS_LOG_INFO("successfully applied the command: %s", cmd.c_str());
}
else
{
// Get the sample rate from the sample object
sai_attribute_t samplepacket_attr;
samplepacket_attr.id = SAI_SAMPLEPACKET_ATTR_SAMPLE_RATE;
if (SAI_STATUS_SUCCESS == get(SAI_OBJECT_TYPE_SAMPLEPACKET, samplepacket_oid, 1, &samplepacket_attr))
{
int rate = samplepacket_attr.value.u32;
// Set the default sample group ID
std::string group("1");
// Check if sampling is already enabled on the port
sai_attribute_t port_attr;
port_attr.id = SAI_PORT_ATTR_INGRESS_SAMPLEPACKET_ENABLE;
// When the sampling parameters are updated,
// a delete and add operation is performed on the sampling session.
// If the sampling session is already created, it is deleted below.
if ((get(SAI_OBJECT_TYPE_PORT, port_id, 1, &port_attr) == SAI_STATUS_SUCCESS) &&
(port_attr.value.oid != SAI_NULL_OBJECT_ID))
{
// Sampling session is already created
SWSS_LOG_INFO("sampling is already enabled on the port: %s .. Deleting it",
sai_serialize_object_id(port_id).c_str());
// Delete the sampling session
cmd.assign("tc qdisc delete dev " + if_name + " handle ffff: ingress");
if (system(cmd.c_str()) == -1)
{
SWSS_LOG_ERROR("unable to delete the sampling session for the interface %s", if_name.c_str());
SWSS_LOG_ERROR("failed to apply the command: %s", cmd.c_str());
return SAI_STATUS_FAILURE;
}
SWSS_LOG_INFO("successfully applied the command: %s", cmd.c_str());
}
// Create a new sampling session
cmd.assign("tc qdisc add dev " + if_name + " handle ffff: ingress");
if (system(cmd.c_str()) == -1)
{
SWSS_LOG_ERROR("unable to create a sampling session for the interface %s", if_name.c_str());
SWSS_LOG_ERROR("failed to apply the command: %s", cmd.c_str());
return SAI_STATUS_FAILURE;
}
SWSS_LOG_INFO("successfully applied the command: %s", cmd.c_str());
// Set the sampling rate of the port
cmd.assign("tc filter add dev " + if_name +
" parent ffff: matchall action sample rate " + std::to_string(rate) +
" group " + group);
if (system(cmd.c_str()) == -1)
{
SWSS_LOG_ERROR("unable to update the sampling rate of the interface %s", if_name.c_str());
SWSS_LOG_ERROR("failed to apply the command: %s", cmd.c_str());
return SAI_STATUS_FAILURE;
}
SWSS_LOG_INFO("successfully applied the command: %s", cmd.c_str());
}
else
{
SWSS_LOG_ERROR("failed to update the port %s, unable to read the sample attr", if_name.c_str());
return SAI_STATUS_FAILURE;
}
}
SWSS_LOG_INFO("successfully modified the sampling config of the port: %s",
sai_serialize_object_id(port_id).c_str());
}
return SAI_STATUS_SUCCESS;
}