Skip to content

Commit 8513506

Browse files
authored
Create Switch and SwitchContainer classes (#549)
* Add Switch class * Add SwitchContainer class * Start using switch container in sairedis * Add remove switch from container
1 parent 567191f commit 8513506

10 files changed

+411
-114
lines changed

lib/inc/Switch.h

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
extern "C" {
4+
#include "saimetadata.h"
5+
}
6+
7+
namespace sairedis
8+
{
9+
class Switch
10+
{
11+
public:
12+
13+
Switch(
14+
_In_ sai_object_id_t switchId);
15+
16+
Switch(
17+
_In_ sai_object_id_t switchId,
18+
_In_ uint32_t attrCount,
19+
_In_ const sai_attribute_t *attrList);
20+
21+
virtual ~Switch() = default;
22+
23+
public:
24+
25+
void clearNotificationsPointers();
26+
27+
/**
28+
* @brief Update switch notifications from attribute list.
29+
*
30+
* A list of attributes which was passed to create switch API.
31+
*/
32+
void updateNotifications(
33+
_In_ uint32_t attrCount,
34+
_In_ const sai_attribute_t *attrList);
35+
36+
const sai_switch_notifications_t& getSwitchNotifications() const;
37+
38+
sai_object_id_t getSwitchId() const;
39+
40+
private:
41+
42+
sai_object_id_t m_switchId;
43+
44+
/**
45+
* @brief Notifications pointers holder.
46+
*
47+
* Each switch instance can have it's own notifications defined.
48+
*/
49+
sai_switch_notifications_t m_switchNotifications;
50+
};
51+
}

lib/inc/SwitchContainer.h

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#pragma once
2+
3+
#include "Switch.h"
4+
5+
#include <memory>
6+
#include <map>
7+
8+
namespace sairedis
9+
{
10+
class SwitchContainer
11+
{
12+
public:
13+
14+
SwitchContainer() = default;
15+
16+
virtual ~SwitchContainer() = default;
17+
18+
public:
19+
20+
/**
21+
* @brief Insert switch to container.
22+
*
23+
* Throws when switch already exists in container.
24+
*/
25+
void insert(
26+
_In_ std::shared_ptr<Switch> sw);
27+
28+
/**
29+
* @brief Remove switch from container.
30+
*
31+
* Throws when switch is not present in container.
32+
*/
33+
void removeSwitch(
34+
_In_ sai_object_id_t switchId);
35+
36+
/**
37+
* @brief Remove switch from container.
38+
*
39+
* Throws when switch is not present in container.
40+
*/
41+
void removeSwitch(
42+
_In_ std::shared_ptr<Switch> sw);
43+
44+
/**
45+
* @brief Get switch from the container.
46+
*
47+
* If switch is not present in container returns NULL pointer.
48+
*/
49+
std::shared_ptr<Switch> getSwitch(
50+
_In_ sai_object_id_t switchId) const;
51+
52+
/**
53+
* @brief Removes all switches from container.
54+
*/
55+
void clear();
56+
57+
/**
58+
* @brief Check whether switch is in the container.
59+
*/
60+
bool contains(
61+
_In_ sai_object_id_t switchId) const;
62+
63+
private:
64+
65+
std::map<sai_object_id_t, std::shared_ptr<Switch>> m_switchMap;
66+
67+
};
68+
};

lib/inc/sai_redis.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ extern "C" {
2525
#include "swss/logger.h"
2626
#include "meta/sai_meta.h"
2727

28+
#include "SwitchContainer.h"
29+
2830
/*
2931
* Switch index is encoded on 1 byte so we can have
3032
* max 0x100 switches at the same time.
@@ -36,12 +38,6 @@ void redis_clear_switch_ids();
3638
void redis_free_virtual_object_id(
3739
_In_ sai_object_id_t object_id);
3840

39-
void clear_notifications();
40-
41-
void check_notifications_pointers(
42-
_In_ uint32_t attr_count,
43-
_In_ const sai_attribute_t *attr_list);
44-
4541
// if we don't receive response from syncd in 60 seconds
4642
// there is something wrong and we should fail
4743
#define GET_RESPONSE_TIMEOUT (60*1000)
@@ -73,6 +69,8 @@ extern std::shared_ptr<swss::ConsumerTable> g_redisGetConsumer;
7369
extern std::shared_ptr<swss::NotificationConsumer> g_redisNotifications;
7470
extern std::shared_ptr<swss::RedisClient> g_redisClient;
7571

72+
extern std::shared_ptr<sairedis::SwitchContainer> g_switchContainer;
73+
7674
extern const sai_acl_api_t redis_acl_api;
7775
extern const sai_bfd_api_t redis_bfd_api;
7876
extern const sai_bmtor_api_t redis_bmtor_api;

lib/src/Makefile.am

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ libsairedis_la_SOURCES = \
5858
sai_redis_generic_stats.cpp \
5959
sai_redis_notifications.cpp \
6060
sai_redis_record.cpp \
61-
Globals.cpp
61+
Globals.cpp \
62+
Switch.cpp \
63+
SwitchContainer.cpp
6264

6365
libsairedis_la_CPPFLAGS = $(DBGFLAGS) $(AM_CPPFLAGS) $(CFLAGS_COMMON)
6466
libsairedis_la_LIBADD = -lhiredis -lswsscommon

lib/src/Switch.cpp

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#include "Switch.h"
2+
3+
#include "swss/logger.h"
4+
5+
#include <cstring>
6+
7+
using namespace sairedis;
8+
9+
Switch::Switch(
10+
_In_ sai_object_id_t switchId):
11+
m_switchId(switchId)
12+
{
13+
SWSS_LOG_ENTER();
14+
15+
if (switchId == SAI_NULL_OBJECT_ID)
16+
{
17+
SWSS_LOG_THROW("switch id can't be NULL");
18+
}
19+
20+
clearNotificationsPointers();
21+
}
22+
23+
Switch::Switch(
24+
_In_ sai_object_id_t switchId,
25+
_In_ uint32_t attrCount,
26+
_In_ const sai_attribute_t *attrList):
27+
Switch(switchId)
28+
{
29+
SWSS_LOG_ENTER();
30+
31+
updateNotifications(attrCount, attrList);
32+
}
33+
34+
void Switch::clearNotificationsPointers()
35+
{
36+
SWSS_LOG_ENTER();
37+
38+
memset(&m_switchNotifications, 0, sizeof(m_switchNotifications));
39+
}
40+
41+
sai_object_id_t Switch::getSwitchId() const
42+
{
43+
SWSS_LOG_ENTER();
44+
45+
return m_switchId;
46+
}
47+
48+
void Switch::updateNotifications(
49+
_In_ uint32_t attrCount,
50+
_In_ const sai_attribute_t *attrList)
51+
{
52+
SWSS_LOG_ENTER();
53+
54+
/*
55+
* This function should only be called on CREATE/SET
56+
* api when object is SWITCH.
57+
*/
58+
59+
for (uint32_t index = 0; index < attrCount; ++index)
60+
{
61+
auto &attr = attrList[index];
62+
63+
auto meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id);
64+
65+
if (meta == NULL)
66+
SWSS_LOG_THROW("failed to find metadata for switch attr %d", attr.id);
67+
68+
if (meta->attrvaluetype != SAI_ATTR_VALUE_TYPE_POINTER)
69+
continue;
70+
71+
switch (attr.id)
72+
{
73+
case SAI_SWITCH_ATTR_SWITCH_STATE_CHANGE_NOTIFY:
74+
m_switchNotifications.on_switch_state_change =
75+
(sai_switch_state_change_notification_fn)attr.value.ptr;
76+
break;
77+
78+
case SAI_SWITCH_ATTR_SHUTDOWN_REQUEST_NOTIFY:
79+
m_switchNotifications.on_switch_shutdown_request =
80+
(sai_switch_shutdown_request_notification_fn)attr.value.ptr;
81+
break;
82+
83+
case SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY:
84+
m_switchNotifications.on_fdb_event =
85+
(sai_fdb_event_notification_fn)attr.value.ptr;
86+
break;
87+
88+
case SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY:
89+
m_switchNotifications.on_port_state_change =
90+
(sai_port_state_change_notification_fn)attr.value.ptr;
91+
break;
92+
93+
case SAI_SWITCH_ATTR_PACKET_EVENT_NOTIFY:
94+
m_switchNotifications.on_packet_event =
95+
(sai_packet_event_notification_fn)attr.value.ptr;
96+
break;
97+
98+
case SAI_SWITCH_ATTR_QUEUE_PFC_DEADLOCK_NOTIFY:
99+
m_switchNotifications.on_queue_pfc_deadlock =
100+
(sai_queue_pfc_deadlock_notification_fn)attr.value.ptr;
101+
break;
102+
103+
default:
104+
SWSS_LOG_ERROR("pointer for %s is not handled, FIXME!", meta->attridname);
105+
break;
106+
}
107+
}
108+
}
109+
110+
const sai_switch_notifications_t& Switch::getSwitchNotifications() const
111+
{
112+
SWSS_LOG_ENTER();
113+
114+
return m_switchNotifications;
115+
}
116+

lib/src/SwitchContainer.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "SwitchContainer.h"
2+
3+
#include "swss/logger.h"
4+
#include "meta/sai_serialize.h"
5+
6+
using namespace sairedis;
7+
8+
void SwitchContainer::insert(
9+
_In_ std::shared_ptr<Switch> sw)
10+
{
11+
SWSS_LOG_ENTER();
12+
13+
auto switchId = sw->getSwitchId();
14+
15+
if (m_switchMap.find(switchId) != m_switchMap.end())
16+
{
17+
SWSS_LOG_THROW("switch %s already exist in container",
18+
sai_serialize_object_id(switchId).c_str());
19+
}
20+
21+
m_switchMap[switchId] = sw;
22+
}
23+
24+
void SwitchContainer::removeSwitch(
25+
_In_ sai_object_id_t switchId)
26+
{
27+
SWSS_LOG_ENTER();
28+
29+
auto it = m_switchMap.find(switchId);
30+
31+
if (it == m_switchMap.end())
32+
{
33+
SWSS_LOG_THROW("switch %s not present in container",
34+
sai_serialize_object_id(switchId).c_str());
35+
}
36+
37+
m_switchMap.erase(it);
38+
}
39+
40+
void SwitchContainer::removeSwitch(
41+
_In_ std::shared_ptr<Switch> sw)
42+
{
43+
SWSS_LOG_ENTER();
44+
45+
removeSwitch(sw->getSwitchId());
46+
}
47+
48+
std::shared_ptr<Switch> SwitchContainer::getSwitch(
49+
_In_ sai_object_id_t switchId) const
50+
{
51+
SWSS_LOG_ENTER();
52+
53+
auto it = m_switchMap.find(switchId);
54+
55+
if (it == m_switchMap.end())
56+
return nullptr;
57+
58+
return it->second;
59+
}
60+
61+
void SwitchContainer::clear()
62+
{
63+
SWSS_LOG_ENTER();
64+
65+
m_switchMap.clear();
66+
}
67+
68+
bool SwitchContainer::contains(
69+
_In_ sai_object_id_t switchId) const
70+
{
71+
SWSS_LOG_ENTER();
72+
73+
return m_switchMap.find(switchId) != m_switchMap.end();
74+
}

lib/src/sai_redis_generic_create.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ sai_object_id_t redis_create_switch_virtual_object_id()
7777
return redis_construct_object_id(SAI_OBJECT_TYPE_SWITCH, index, index);
7878
}
7979

80+
// TODO must be protected using api MUTEX (but first remove usage from metadata) - use std::function
8081
sai_object_type_t sai_object_type_query(
8182
_In_ sai_object_id_t object_id)
8283
{
@@ -104,6 +105,7 @@ sai_object_type_t sai_object_type_query(
104105
return ot;
105106
}
106107

108+
// TODO must be protected using api MUTEX (but first remove usage from metadata) - use std::function
107109
sai_object_id_t sai_switch_id_query(
108110
_In_ sai_object_id_t oid)
109111
{

0 commit comments

Comments
 (0)