vslib/SwitchStateBase.h (523 lines of code) (raw):
#pragma once
#include "SwitchState.h"
#include "FdbInfo.h"
#include "HostInterfaceInfo.h"
#include "WarmBootState.h"
#include "SwitchConfig.h"
#include "RealObjectIdManager.h"
#include "EventPayloadNetLinkMsg.h"
#include "MACsecManager.h"
#include <set>
#include <unordered_set>
#include <vector>
#define SAI_VS_FDB_INFO "SAI_VS_FDB_INFO"
#define DEFAULT_VLAN_NUMBER 1
#define MAX_OBJLIST_LEN 128
#define CHECK_STATUS(status) { \
sai_status_t _status = (status); \
if (_status != SAI_STATUS_SUCCESS) { return _status; } }
namespace saivs
{
class SwitchStateBase:
public SwitchState
{
public:
typedef std::map<sai_object_id_t, std::shared_ptr<SwitchStateBase>> SwitchStateMap;
public:
SwitchStateBase(
_In_ sai_object_id_t switch_id,
_In_ std::shared_ptr<RealObjectIdManager> manager,
_In_ std::shared_ptr<SwitchConfig> config);
SwitchStateBase(
_In_ sai_object_id_t switch_id,
_In_ std::shared_ptr<RealObjectIdManager> manager,
_In_ std::shared_ptr<SwitchConfig> config,
std::shared_ptr<WarmBootState> warmBootState);
virtual ~SwitchStateBase();
protected:
virtual sai_status_t set_switch_mac_address();
virtual sai_status_t set_switch_supported_object_types();
virtual sai_status_t set_switch_default_attributes();
virtual sai_status_t create_default_hash();
virtual sai_status_t create_default_vlan();
virtual sai_status_t create_cpu_port();
virtual sai_status_t create_default_1q_bridge();
virtual sai_status_t create_ports();
virtual sai_status_t set_port_list();
virtual sai_status_t set_port_capabilities();
virtual sai_status_t create_fabric_ports();
virtual sai_status_t set_fabric_port_list();
virtual sai_status_t create_default_virtual_router();
virtual sai_status_t create_default_stp_instance();
virtual sai_status_t create_default_trap_group();
virtual sai_status_t create_ingress_priority_groups_per_port(
_In_ sai_object_id_t port_id);
virtual sai_status_t create_ingress_priority_groups();
virtual sai_status_t create_vlan_members();
virtual sai_status_t create_bridge_ports();
virtual sai_status_t set_acl_entry_min_prio();
virtual sai_status_t set_acl_capabilities();
virtual sai_status_t set_maximum_number_of_childs_per_scheduler_group();
virtual sai_status_t set_number_of_ecmp_groups();
virtual sai_status_t set_static_crm_values();
virtual sai_status_t set_static_acl_resource_list(
_In_ sai_switch_attr_t acl_resource,
_In_ int max_count);
sai_status_t filter_available_lanes(
_Inout_ std::vector<std::vector<uint32_t>> &lanes_vector);
sai_status_t create_system_ports(
_In_ int32_t voq_switch_id,
_In_ uint32_t sys_port_count,
_In_ const sai_system_port_config_t *sys_port_cfg_list);
sai_status_t create_voqs();
sai_status_t create_voq_per_sysport(
_In_ sai_object_id_t sys_port_id);
sai_status_t set_system_port_list();
public:
virtual sai_status_t initialize_default_objects(
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
protected:
virtual sai_status_t create_port_dependencies(
_In_ sai_object_id_t port_id);
sai_status_t initialize_voq_switch_objects(
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
protected : // refresh
virtual sai_status_t refresh_ingress_priority_group(
_In_ const sai_attr_metadata_t *meta,
_In_ sai_object_id_t port_id);
virtual sai_status_t refresh_qos_queues(
_In_ const sai_attr_metadata_t *meta,
_In_ sai_object_id_t port_id);
virtual sai_status_t refresh_scheduler_groups(
_In_ const sai_attr_metadata_t *meta,
_In_ sai_object_id_t port_id);
virtual sai_status_t refresh_bridge_port_list(
_In_ const sai_attr_metadata_t *meta,
_In_ sai_object_id_t bridge_id);
virtual sai_status_t refresh_vlan_member_list(
_In_ const sai_attr_metadata_t *meta,
_In_ sai_object_id_t vlan_id);
virtual sai_status_t refresh_port_list(
_In_ const sai_attr_metadata_t *meta);
virtual sai_status_t refresh_system_port_list(
_In_ const sai_attr_metadata_t *meta);
virtual sai_status_t refresh_macsec_sci_in_ingress_macsec_acl(
_In_ sai_object_id_t object_id);
virtual sai_status_t refresh_queue_pause_status(
_In_ sai_object_id_t object_id);
virtual sai_status_t refresh_macsec_sa_stat(
_In_ sai_object_id_t object_id);
virtual sai_status_t refresh_port_serdes_id(
_In_ sai_object_id_t bridge_id);
virtual sai_status_t refresh_port_oper_speed(
_In_ sai_object_id_t port_id);
virtual sai_status_t refresh_acl_table_entries(
_In_ sai_object_id_t acl_table_id);
virtual sai_status_t refresh_acl_table_counters(
_In_ sai_object_id_t acl_table_id);
public:
virtual sai_status_t warm_boot_initialize_objects();
protected:
virtual sai_status_t refresh_read_only(
_In_ const sai_attr_metadata_t *meta,
_In_ sai_object_id_t object_id);
protected:
virtual sai_status_t warm_update_queues();
virtual sai_status_t warm_update_scheduler_groups();
virtual sai_status_t warm_update_ingress_priority_groups();
virtual sai_status_t warm_update_switch();
virtual sai_status_t warm_update_cpu_queues();
protected: // TODO should be pure
virtual sai_status_t create_cpu_qos_queues(
_In_ sai_object_id_t port_id);
virtual sai_status_t create_qos_queues_per_port(
_In_ sai_object_id_t port_id);
virtual sai_status_t create_qos_queues();
virtual sai_status_t create_scheduler_group_tree(
_In_ const std::vector<sai_object_id_t>& sgs,
_In_ sai_object_id_t port_id);
virtual sai_status_t create_scheduler_groups_per_port(
_In_ sai_object_id_t port_id);
virtual sai_status_t create_scheduler_groups();
virtual sai_status_t create_port_serdes();
virtual sai_status_t create_port_serdes_per_port(
_In_ sai_object_id_t port_id);
protected: // will generate new OID
virtual sai_status_t create(
_In_ sai_object_type_t object_type,
_Out_ sai_object_id_t *object_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
virtual sai_status_t remove(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id);
virtual sai_status_t set(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t* attr);
virtual sai_status_t get(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t attr_count,
_Out_ sai_attribute_t *attr_list);
public:
virtual sai_status_t create(
_In_ sai_object_type_t object_type,
_In_ const std::string &serializedObjectId,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
virtual sai_status_t remove(
_In_ sai_object_type_t object_type,
_In_ const std::string &serializedObjectId);
virtual sai_status_t set(
_In_ sai_object_type_t objectType,
_In_ const std::string &serializedObjectId,
_In_ const sai_attribute_t* attr);
virtual sai_status_t get(
_In_ sai_object_type_t object_type,
_In_ const std::string &serializedObjectId,
_In_ uint32_t attr_count,
_Out_ sai_attribute_t *attr_list);
virtual sai_status_t bulkCreate(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ const std::vector<std::string> &serialized_object_ids,
_In_ const uint32_t *attr_count,
_In_ const sai_attribute_t **attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses);
virtual sai_status_t bulkRemove(
_In_ sai_object_type_t object_type,
_In_ const std::vector<std::string> &serialized_object_ids,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses);
virtual sai_status_t bulkSet(
_In_ sai_object_type_t object_type,
_In_ const std::vector<std::string> &serialized_object_ids,
_In_ const sai_attribute_t *attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses);
virtual sai_status_t bulkGet(
_In_ sai_object_type_t object_type,
_In_ const std::vector<std::string> &serialized_object_ids,
_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);
virtual sai_status_t queryAttrEnumValuesCapability(
_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);
virtual sai_status_t queryStatsCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_Inout_ sai_stat_capability_list_t *stats_capability);
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);
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 *attr_capability);
protected:
virtual sai_status_t remove_internal(
_In_ sai_object_type_t object_type,
_In_ const std::string &serializedObjectId);
virtual sai_status_t create_internal(
_In_ sai_object_type_t object_type,
_In_ const std::string &serializedObjectId,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
virtual sai_status_t set_internal(
_In_ sai_object_type_t objectType,
_In_ const std::string &serializedObjectId,
_In_ const sai_attribute_t* attr);
private:
sai_object_type_t objectTypeQuery(
_In_ sai_object_id_t objectId);
sai_object_id_t switchIdQuery(
_In_ sai_object_id_t objectId);
public:
void processFdbEntriesForAging();
private: // fdb related
void updateLocalDB(
_In_ const sai_fdb_event_notification_data_t &data,
_In_ sai_fdb_event_t fdb_event);
void processFdbInfo(
_In_ const FdbInfo &fi,
_In_ sai_fdb_event_t fdb_event);
void findBridgeVlanForPortVlan(
_In_ sai_object_id_t port_id,
_In_ sai_vlan_id_t vlan_id,
_Inout_ sai_object_id_t &bv_id,
_Inout_ sai_object_id_t &bridge_port_id);
bool getLagFromPort(
_In_ sai_object_id_t port_id,
_Inout_ sai_object_id_t& lag_id);
bool isLagOrPortRifBased(
_In_ sai_object_id_t lag_or_port_id);
public:
void process_packet_for_fdb_event(
_In_ sai_object_id_t portId,
_In_ const std::string& name,
_In_ const uint8_t *buffer,
_In_ size_t size);
void debugSetStats(
_In_ sai_object_id_t oid,
_In_ const std::map<sai_stat_id_t, uint64_t>& stats);
protected: // custom port
sai_status_t createPort(
_In_ sai_object_id_t object_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t removePort(
_In_ sai_object_id_t objectId);
sai_status_t setPort(
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t* attr);
bool isPortReadyToBeRemove(
_In_ sai_object_id_t portId);
std::vector<sai_object_id_t> getPortDependencies(
_In_ sai_object_id_t portId);
sai_status_t check_port_dependencies(
_In_ sai_object_id_t port_id,
_Out_ std::vector<sai_object_id_t>& dep);
bool check_port_reference_count(
_In_ sai_object_id_t port_id);
bool get_object_list(
_In_ sai_object_id_t object_id,
_In_ sai_attr_id_t attr_id,
_Out_ std::vector<sai_object_id_t>& objlist);
bool get_port_queues(
_In_ sai_object_id_t port_id,
_Out_ std::vector<sai_object_id_t>& queues);
bool get_port_ipgs(
_In_ sai_object_id_t port_id,
_Out_ std::vector<sai_object_id_t>& ipgs);
bool get_port_sg(
_In_ sai_object_id_t port_id,
_Out_ std::vector<sai_object_id_t>& sg);
bool check_object_default_state(
_In_ sai_object_id_t object_id);
bool check_object_list_default_state(
_Out_ const std::vector<sai_object_id_t>& objlist);
sai_status_t createVoqSystemNeighborEntry(
_In_ const std::string &serializedObjectId,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
protected: // custom debug counter
uint32_t getNewDebugCounterIndex();
void releaseDebugCounterIndex(
_In_ uint32_t index);
sai_status_t createDebugCounter(
_In_ sai_object_id_t object_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t removeDebugCounter(
_In_ sai_object_id_t objectId);
public:
static int promisc(
_In_ const char *dev);
protected: // custom hostif
sai_status_t createHostif(
_In_ sai_object_id_t object_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t removeHostif(
_In_ sai_object_id_t objectId);
sai_status_t vs_remove_hostif_tap_interface(
_In_ sai_object_id_t hostif_id);
sai_status_t vs_create_hostif_tap_interface(
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
bool hostif_create_tap_veth_forwarding(
_In_ const std::string &tapname,
_In_ int tapfd,
_In_ sai_object_id_t port_id);
static int vs_create_tap_device(
_In_ const char *dev,
_In_ int flags);
static int vs_set_dev_mac_address(
_In_ const char *dev,
_In_ const sai_mac_t& mac);
static int get_default_gw_mac_address(
_Out_ sai_mac_t& mac);
int vs_set_dev_mtu(
_In_ const char*name,
_In_ int mtu);
int ifup(
_In_ const char *dev,
_In_ sai_object_id_t port_id,
_In_ bool up,
_In_ bool explicitNotification);
std::string vs_get_veth_name(
_In_ const std::string& tapname,
_In_ sai_object_id_t port_id);
void send_port_oper_status_notification(
_In_ sai_object_id_t port_id,
_In_ sai_port_oper_status_t status,
_In_ bool force);
bool hasIfIndex(
_In_ int ifIndex) const;
bool vs_get_oper_speed(
_In_ sai_object_id_t port_id,
_Out_ uint32_t& speed);
public: // TODO move inside warm boot load state
sai_status_t vs_recreate_hostif_tap_interfaces();
void update_port_oper_status(
_In_ sai_object_id_t port_id,
_In_ sai_port_oper_status_t port_oper_status);
std::string dump_switch_database_for_warm_restart() const;
void syncOnLinkMsg(
_In_ std::shared_ptr<EventPayloadNetLinkMsg> payload);
void send_fdb_event_notification(
_In_ const sai_fdb_event_notification_data_t& data);
protected:
void findObjects(
_In_ sai_object_type_t object_type,
_In_ const sai_attribute_t &expect,
_Out_ std::vector<sai_object_id_t> &objects);
bool dumpObject(
_In_ const sai_object_id_t object_id,
_Out_ std::vector<sai_attribute_t> &attrs);
protected:
sai_status_t setAclEntry(
_In_ sai_object_id_t entry_id,
_In_ const sai_attribute_t* attr);
sai_status_t setAclEntryMACsecFlowActive(
_In_ sai_object_id_t entry_id,
_In_ const sai_attribute_t* attr);
sai_status_t setMACsecSA(
_In_ sai_object_id_t macsec_sa_id,
_In_ const sai_attribute_t* attr);
sai_status_t createMACsecPort(
_In_ sai_object_id_t macsec_sa_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t createMACsecSA(
_In_ sai_object_id_t macsec_sa_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t createMACsecSC(
_In_ sai_object_id_t macsec_sa_id,
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list);
sai_status_t removeMACsecPort(
_In_ sai_object_id_t macsec_port_id);
sai_status_t removeMACsecSC(
_In_ sai_object_id_t macsec_sc_id);
sai_status_t removeMACsecSA(
_In_ sai_object_id_t macsec_sa_id);
sai_status_t getACLTable(
_In_ sai_object_id_t entry_id,
_Out_ sai_object_id_t &table_id);
sai_status_t findPortByMACsecFlow(
_In_ sai_object_id_t macsec_flow_id,
_Out_ sai_object_id_t &line_port_id);
std::shared_ptr<HostInterfaceInfo> findHostInterfaceInfoByPort(
_In_ sai_object_id_t line_port_id);
sai_status_t loadMACsecAttrFromMACsecPort(
_In_ sai_object_id_t object_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_Out_ MACsecAttr &macsec_attr);
sai_status_t loadMACsecAttrFromMACsecSC(
_In_ sai_object_id_t object_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_Out_ MACsecAttr &macsec_attr);
sai_status_t loadMACsecAttrFromMACsecSA(
_In_ sai_object_id_t object_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_Out_ MACsecAttr &macsec_attr);
sai_status_t loadMACsecAttr(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list,
_Out_ MACsecAttr &macsec_attr);
sai_status_t loadMACsecAttr(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_Out_ MACsecAttr &macsec_attr);
sai_status_t loadMACsecAttrsFromACLEntry(
_In_ sai_object_id_t entry_id,
_In_ const sai_attribute_t* entry_attr,
_In_ sai_object_type_t object_type,
_Out_ std::vector<MACsecAttr> &macsec_attrs);
sai_status_t getMACsecSAPacketNumber(
_In_ sai_object_id_t macsec_sa_id,
_Out_ sai_attribute_t &attr);
void retryCreateIngressMaCsecSAs();
MACsecManager m_macsecManager;
std::unordered_map<sai_object_id_t, sai_object_id_t> m_macsecFlowPortMap;
std::unordered_set<MACsecAttr, MACsecAttr::Hash> m_uncreatedIngressMACsecSAs;
protected:
constexpr static const int maxDebugCounters = 32;
std::unordered_set<uint32_t> m_indices;
protected:
std::vector<sai_object_id_t> m_port_list;
std::vector<sai_object_id_t> m_bridge_port_list_port_based;
std::vector<sai_object_id_t> m_fabric_port_list;
std::vector<sai_acl_action_type_t> m_ingress_acl_action_list;
std::vector<sai_acl_action_type_t> m_egress_acl_action_list;
sai_object_id_t m_cpu_port_id;
sai_object_id_t m_default_1q_bridge;
sai_object_id_t m_default_bridge_port_1q_router;
sai_object_id_t m_default_vlan_id;
sai_object_id_t m_ecmp_hash_id;
sai_object_id_t m_lag_hash_id;
std::vector<sai_object_id_t> m_system_port_list;
protected:
constexpr static const int m_maxIPv4RouteEntries = 100000;
constexpr static const int m_maxIPv6RouteEntries = 10000;
constexpr static const int m_maxIPv4NextHopEntries = 32000;
constexpr static const int m_maxIPv6NextHopEntries = 32000;
constexpr static const int m_maxIPv4NeighborEntries = 4000;
constexpr static const int m_maxIPv6NeighborEntries = 2000;
constexpr static const int m_maxNextHopGroupMemberEntries = 16000;
constexpr static const int m_maxNextHopGroupEntries = 400;
constexpr static const int m_maxFdbEntries = 800;
constexpr static const int m_maxSNATEntries = 100;
constexpr static const int m_maxDNATEntries = 100;
constexpr static const int m_maxIPMCEntries = 100;
constexpr static const int m_maxDoubleNATEntries = 50; /* Half of single NAT entry */
constexpr static const int m_maxAclTables = 3;
constexpr static const int m_maxAclTableGroups = 200;
constexpr static const int m_maxAclTableEntries = 1000;
constexpr static const int m_maxAclTableCounters = 1000;
protected:
virtual sai_status_t queryTunnelPeerModeCapability(
_Inout_ sai_s32_list_t *enum_values_capability);
virtual sai_status_t queryVlanfloodTypeCapability(
_Inout_ sai_s32_list_t *enum_values_capability);
virtual sai_status_t queryNextHopGroupTypeCapability(
_Inout_ sai_s32_list_t *enum_values_capability);
virtual sai_status_t queryHashNativeHashFieldListCapability(
_Inout_ sai_s32_list_t *enum_values_capability);
virtual sai_status_t querySwitchHashAlgorithmCapability(
_Inout_ sai_s32_list_t *enum_values_capability);
virtual sai_status_t queryPortAutonegFecOverrideSupportCapability(
_Out_ sai_attr_capability_t *attr_capability);
public: // TODO private
std::set<FdbInfo> m_fdb_info_set;
std::map<std::string, std::shared_ptr<HostInterfaceInfo>> m_hostif_info_map;
std::shared_ptr<RealObjectIdManager> m_realObjectIdManager;
};
}