Skip to content

Commit 7114352

Browse files
authored
Store mirror session state in StateDB (sonic-net#609)
* Store mirror state in StateDB * Add MIRROR_SESSION_VLAN_HEADER_VALID * Fix setSessionStatus on MIRROR_SESSION_STATUS * Fix test * (comment) * Fix deactivateSession storing * Add test
1 parent fa2b5d9 commit 7114352

File tree

6 files changed

+120
-85
lines changed

6 files changed

+120
-85
lines changed

orchagent/aclorch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ bool AclRuleMirror::create()
961961
bool state = false;
962962
sai_object_id_t oid = SAI_NULL_OBJECT_ID;
963963

964-
if (!m_pMirrorOrch->getSessionState(m_sessionName, state))
964+
if (!m_pMirrorOrch->getSessionStatus(m_sessionName, state))
965965
{
966966
throw runtime_error("Failed to get mirror session state");
967967
}

orchagent/mirrororch.cpp

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,26 @@
44
#include <utility>
55
#include <exception>
66

7+
#include "sai_serialize.h"
78
#include "orch.h"
89
#include "logger.h"
910
#include "swssnet.h"
1011
#include "converter.h"
1112
#include "mirrororch.h"
1213

13-
#define MIRROR_SESSION_STATUS "status"
14-
#define MIRROR_SESSION_STATUS_ACTIVE "active"
15-
#define MIRROR_SESSION_STATUS_INACTIVE "inactive"
16-
#define MIRROR_SESSION_SRC_IP "src_ip"
17-
#define MIRROR_SESSION_DST_IP "dst_ip"
18-
#define MIRROR_SESSION_GRE_TYPE "gre_type"
19-
#define MIRROR_SESSION_DSCP "dscp"
20-
#define MIRROR_SESSION_TTL "ttl"
21-
#define MIRROR_SESSION_QUEUE "queue"
14+
#define MIRROR_SESSION_STATUS "status"
15+
#define MIRROR_SESSION_STATUS_ACTIVE "active"
16+
#define MIRROR_SESSION_STATUS_INACTIVE "inactive"
17+
#define MIRROR_SESSION_SRC_IP "src_ip"
18+
#define MIRROR_SESSION_DST_IP "dst_ip"
19+
#define MIRROR_SESSION_GRE_TYPE "gre_type"
20+
#define MIRROR_SESSION_DSCP "dscp"
21+
#define MIRROR_SESSION_TTL "ttl"
22+
#define MIRROR_SESSION_QUEUE "queue"
23+
#define MIRROR_SESSION_DST_MAC_ADDRESS "dst_mac"
24+
#define MIRROR_SESSION_MONITOR_PORT "monitor_port"
25+
#define MIRROR_SESSION_ROUTE_PREFIX "route_prefix"
26+
#define MIRROR_SESSION_VLAN_HEADER_VALID "vlan_header_valid"
2227

2328
#define MIRROR_SESSION_DEFAULT_VLAN_PRI 0
2429
#define MIRROR_SESSION_DEFAULT_VLAN_CFI 0
@@ -56,14 +61,14 @@ MirrorEntry::MirrorEntry(const string& platform) :
5661
nexthopInfo.prefix = IpPrefix("0.0.0.0/0");
5762
}
5863

59-
MirrorOrch::MirrorOrch(TableConnector appDbConnector, TableConnector confDbConnector,
64+
MirrorOrch::MirrorOrch(TableConnector stateDbConnector, TableConnector confDbConnector,
6065
PortsOrch *portOrch, RouteOrch *routeOrch, NeighOrch *neighOrch, FdbOrch *fdbOrch) :
6166
Orch(confDbConnector.first, confDbConnector.second),
6267
m_portsOrch(portOrch),
6368
m_routeOrch(routeOrch),
6469
m_neighOrch(neighOrch),
6570
m_fdbOrch(fdbOrch),
66-
m_mirrorTableProducer(appDbConnector.first, appDbConnector.second)
71+
m_mirrorTable(stateDbConnector.first, stateDbConnector.second)
6772
{
6873
m_portsOrch->attach(this);
6974
m_neighOrch->attach(this);
@@ -121,7 +126,7 @@ bool MirrorOrch::sessionExists(const string& name)
121126
return m_syncdMirrors.find(name) != m_syncdMirrors.end();
122127
}
123128

124-
bool MirrorOrch::getSessionState(const string& name, bool& state)
129+
bool MirrorOrch::getSessionStatus(const string& name, bool& state)
125130
{
126131
SWSS_LOG_ENTER();
127132

@@ -294,22 +299,45 @@ void MirrorOrch::deleteEntry(const string& name)
294299
SWSS_LOG_NOTICE("Removed mirror session %s", name.c_str());
295300
}
296301

297-
bool MirrorOrch::setSessionState(const string& name, MirrorEntry& session)
302+
void MirrorOrch::setSessionState(const string& name, const MirrorEntry& session, const string& attr)
298303
{
299304
SWSS_LOG_ENTER();
300305

301306
SWSS_LOG_INFO("Setting mirroring sessions %s state\n", name.c_str());
302307

303308
vector<FieldValueTuple> fvVector;
309+
string value;
310+
if (attr.empty() || attr == MIRROR_SESSION_STATUS)
311+
{
312+
value = session.status ? MIRROR_SESSION_STATUS_ACTIVE : MIRROR_SESSION_STATUS_INACTIVE;
313+
fvVector.emplace_back(MIRROR_SESSION_STATUS, value);
314+
}
304315

305-
string status = session.status ? MIRROR_SESSION_STATUS_ACTIVE : MIRROR_SESSION_STATUS_INACTIVE;
316+
if (attr.empty() || attr == MIRROR_SESSION_MONITOR_PORT)
317+
{
318+
value = sai_serialize_object_id(session.neighborInfo.portId);
319+
fvVector.emplace_back(MIRROR_SESSION_MONITOR_PORT, value);
320+
}
306321

307-
FieldValueTuple t(MIRROR_SESSION_STATUS, status);
308-
fvVector.push_back(t);
322+
if (attr.empty() || attr == MIRROR_SESSION_DST_MAC_ADDRESS)
323+
{
324+
value = session.neighborInfo.mac.to_string();
325+
fvVector.emplace_back(MIRROR_SESSION_DST_MAC_ADDRESS, value);
326+
}
309327

310-
m_mirrorTableProducer.set(name, fvVector);
328+
if (attr.empty() || attr == MIRROR_SESSION_ROUTE_PREFIX)
329+
{
330+
value = session.nexthopInfo.prefix.to_string();
331+
fvVector.emplace_back(MIRROR_SESSION_ROUTE_PREFIX, value);
332+
}
311333

312-
return true;
334+
if (attr.empty() || attr == MIRROR_SESSION_VLAN_HEADER_VALID)
335+
{
336+
value = to_string(session.neighborInfo.port.m_type == Port::VLAN);
337+
fvVector.emplace_back(MIRROR_SESSION_VLAN_HEADER_VALID, value);
338+
}
339+
340+
m_mirrorTable.set(name, fvVector);
313341
}
314342

315343
bool MirrorOrch::getNeighborInfo(const string& name, MirrorEntry& session)
@@ -533,11 +561,7 @@ bool MirrorOrch::activateSession(const string& name, MirrorEntry& session)
533561
}
534562

535563
session.status = true;
536-
537-
if (!setSessionState(name, session))
538-
{
539-
throw runtime_error("Failed to test session state");
540-
}
564+
setSessionState(name, session);
541565

542566
MirrorSessionUpdate update = { name, true };
543567
notify(SUBJECT_TYPE_MIRROR_SESSION_CHANGE, static_cast<void *>(&update));
@@ -566,10 +590,8 @@ bool MirrorOrch::deactivateSession(const string& name, MirrorEntry& session)
566590

567591
session.status = false;
568592

569-
if (!setSessionState(name, session))
570-
{
571-
throw runtime_error("Failed to test session state");
572-
}
593+
// Store whole state into StateDB, since it is far from that frequent it's durable
594+
setSessionState(name, session);
573595

574596
SWSS_LOG_NOTICE("Deactive mirror session %s", name.c_str());
575597

@@ -597,6 +619,8 @@ bool MirrorOrch::updateSessionDstMac(const string& name, MirrorEntry& session)
597619
SWSS_LOG_NOTICE("Update mirror session %s destination MAC to %s",
598620
name.c_str(), session.neighborInfo.mac.to_string().c_str());
599621

622+
setSessionState(name, session, MIRROR_SESSION_DST_MAC_ADDRESS);
623+
600624
return true;
601625
}
602626

@@ -625,6 +649,7 @@ bool MirrorOrch::updateSessionDstPort(const string& name, MirrorEntry& session)
625649
SWSS_LOG_NOTICE("Update mirror session %s monitor port to %s",
626650
name.c_str(), port.m_alias.c_str());
627651

652+
setSessionState(name, session, MIRROR_SESSION_MONITOR_PORT);
628653

629654
return true;
630655
}
@@ -682,6 +707,8 @@ bool MirrorOrch::updateSessionType(const string& name, MirrorEntry& session)
682707
SWSS_LOG_NOTICE("Update mirror session %s VLAN to %s",
683708
name.c_str(), session.neighborInfo.port.m_alias.c_str());
684709

710+
setSessionState(name, session, MIRROR_SESSION_VLAN_HEADER_VALID);
711+
685712
return true;
686713
}
687714

@@ -705,6 +732,8 @@ void MirrorOrch::updateNextHop(const NextHopUpdate& update)
705732

706733
session.nexthopInfo.prefix = update.prefix;
707734

735+
setSessionState(name, session, MIRROR_SESSION_ROUTE_PREFIX);
736+
708737
// This is the ECMP scenario that the new next hop group contains the previous
709738
// next hop. There is no need to update this session's monitor port.
710739
if (update.nexthopGroup != IpAddresses() &&

orchagent/mirrororch.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/*
2121
* Contains session data specified by user in config file
2222
* and data required for MAC address and port resolution
23-
* */
23+
*/
2424
struct MirrorEntry
2525
{
2626
bool status;
@@ -69,7 +69,7 @@ class MirrorOrch : public Orch, public Observer, public Subject
6969

7070
void update(SubjectType, void *);
7171
bool sessionExists(const string&);
72-
bool getSessionState(const string&, bool&);
72+
bool getSessionStatus(const string&, bool&);
7373
bool getSessionOid(const string&, sai_object_id_t&);
7474
bool increaseRefCount(const string&);
7575
bool decreaseRefCount(const string&);
@@ -80,7 +80,7 @@ class MirrorOrch : public Orch, public Observer, public Subject
8080
NeighOrch *m_neighOrch;
8181
FdbOrch *m_fdbOrch;
8282

83-
Table m_mirrorTableProducer;
83+
Table m_mirrorTable;
8484

8585
MirrorTable m_syncdMirrors;
8686

@@ -93,7 +93,12 @@ class MirrorOrch : public Orch, public Observer, public Subject
9393
bool updateSessionDstMac(const string&, MirrorEntry&);
9494
bool updateSessionDstPort(const string&, MirrorEntry&);
9595
bool updateSessionType(const string&, MirrorEntry&);
96-
bool setSessionState(const string&, MirrorEntry&);
96+
97+
/*
98+
* Store mirror session state in StateDB
99+
* attr is the field name will be stored, if empty then all fields will be stored
100+
*/
101+
void setSessionState(const std::string& name, const MirrorEntry& session, const std::string& attr = "");
97102
bool getNeighborInfo(const string&, MirrorEntry&);
98103

99104
void updateNextHop(const NextHopUpdate&);

orchagent/orchdaemon.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ bool OrchDaemon::init()
101101
};
102102
gBufferOrch = new BufferOrch(m_configDb, buffer_tables);
103103

104-
TableConnector appDbMirrorSession(m_applDb, APP_MIRROR_SESSION_TABLE_NAME);
104+
TableConnector stateDbMirrorSession(m_stateDb, APP_MIRROR_SESSION_TABLE_NAME);
105105
TableConnector confDbMirrorSession(m_configDb, CFG_MIRROR_SESSION_TABLE_NAME);
106-
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, gRouteOrch, gNeighOrch, gFdbOrch);
106+
MirrorOrch *mirror_orch = new MirrorOrch(stateDbMirrorSession, confDbMirrorSession, gPortsOrch, gRouteOrch, gNeighOrch, gFdbOrch);
107107
VRFOrch *vrf_orch = new VRFOrch(m_configDb, CFG_VRF_TABLE_NAME);
108108

109109
TableConnector confDbAclTable(m_configDb, CFG_ACL_TABLE_NAME);

tests/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def __init__(self, name=None):
186186
network_mode="container:%s" % self.ctn_sw.name,
187187
volumes={ self.mount: { 'bind': '/var/run/redis', 'mode': 'rw' } })
188188

189+
self.appldb = None
189190
try:
190191
self.ctn.exec_run("sysctl -w net.ipv6.conf.all.disable_ipv6=0")
191192
self.check_ready()
@@ -196,7 +197,8 @@ def __init__(self, name=None):
196197
raise
197198

198199
def destroy(self):
199-
del self.appldb
200+
if self.appldb:
201+
del self.appldb
200202
if self.cleanup:
201203
self.ctn.remove(force=True)
202204
self.ctn_sw.remove(force=True)

0 commit comments

Comments
 (0)